I know how to encrypt text using an RSA certificate, but when I try the same thing with a certificate based on an Elliptic curve, I seem to be missing pieces necessary to complete the encryption phase. With an RSA key, the code looks like this:
#This script assumes that you have a CER file that pertains to an imported private key. #Taking a string and formating for encryption $bytes += [byte[]][char[]] "A Simple String to Encrypt" #Get the certificate [Byte[]] $certbytes = get-content -encoding byte -path .\PublicKeyCert.cer $cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2(,$certbytes) #If you look at $Cert.PublicKey.key, the field returns the public key when #using RSA keys. This field is not populated for elliptic curve keys. #Use the public key to encrypt the bytes from the string we started with. $cipherbytes = $cert.publickey.key.encrypt($bytes,$false) #Output the encrypted text to a file... $cipherbytes | set-content -encoding byte -path (".\TestPassword.Txt") -force
When I walk through the script I notice that $Cert.PublicKey.key is empty on an elliptic curve certificate. I can see that the public key is present when I look at the certificate with the GUI, and I have notice that Microsoft says that you cannot use $Cert.PublicKey.key with elliptic curve keys. So the question is this: How do you encrypt text (and hopefully decrypt text) using an elliptic curve based key?
I am creating the key using an INF file and certreq using the -new switch. Below is the contents of my INF.
;----------------- request.inf ----------------- [Version] Signature="$Windows NT$" [NewRequest] Subject = "CN=SpecialServices, OU=TinCan, O=LackOf, L=Lost, S=Confusion, C=None" KeySpec = 0 KeyLength = 256 Exportable = TRUE FriendlyName = "Admin Password Protection" MachineKeySet = FALSE SMIME = False PrivateKeyArchive = FALSE UserProtected = FALSE UseExistingKeySet = FALSE ProviderName="Microsoft Software Key Storage Provider" KeyAlgorithm = ECDSA_P256 HashAlgorithm = sha256 RequestType = Cert KeyUsage = 0xa0 [EnhancedKeyUsageExtension] OID=1.3.6.1.5.5.7.3.1 ; this is for client Authentication
This is based on a script I found on SANs that encrypts and decrypts passwords. RSA is not an encryption I am comfortable using, so I am looking to change the script to use elliptic curve. As noted though, publickey.key is not supported for elliptic curve. The examples I have found for Elliptic curve encryption seem to assume two people are communicating. For my purposes, there is no second person. We cannot use the private key to encrypt because every system needs to encrypt a message. We do not want to distribute the private key to every system. We just want each system to encrypt a message that can only be decrypted by someone who has been given the private key. 5000 systems encrypt messages, Three people can read them... No systems can read them.
Any thoughts on how this is suppose to work?