We are using the PKCS#7 / CMS data format standard to encrypt/decrypt/sign/verify sensitive payloads. Currently we're using 2048 and 4096 bit RSA certificates (and keys) for our PKCS7 / CMS and its fine (see RSA working code below).
We want to add support for ECC (specifically the secp521 curve) but .NET 4.5 has spotty support for ECC despite it being NSA suite B's only PKI algorithm (although at 256 and 384 prime moduli).
Question
What EC Certificate + keys can I use that would be compatible with .NET 4.5 and the code below (perhaps with some edits)? I'm looking for specific curves, in fact creating the certificate + keys via OpenSSL (or other common or free tool) would make for an extremely concrete answer and would be appreciated!
Working, simplified code for RSA-4096 certificate + keys
public byte[] Encrypt(byte[] plainBytes, X509Certificate2 recipientCert)
{
// create ContentInfo
ContentInfo plainContent = new ContentInfo(plainBytes);
// EnvelopedCms represents encrypted data
//Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.46"); // AES-256-GCM, .NET doesn't have it :(
Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.42"); // AES-256-CBC
EnvelopedCms encryptedData = new EnvelopedCms(plainContent, new AlgorithmIdentifier(encryptAlgoOid));
// add a recipient
CmsRecipient recipient = new CmsRecipient(recipientCert);
// encrypt data with public key of recipient
encryptedData.Encrypt(recipient);
// create PKCS #7 byte array
byte[] encryptedBytes = encryptedData.Encode();
// return encrypted data
return encryptedBytes;
}
Exception when using ECC certificate + keys
System.Security.Cryptography.CryptographicException: Unknown error "-1073741637".
at System.Security.Cryptography.Pkcs.EnvelopedCms.EncryptContent(CmsRecipientCollection recipients)
at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipientCollection recipients)
at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipient recipient)
Working, simplified code for RSA-4096 certificate + keys
public byte[] Sign(byte[] data, X509Certificate2 signingCert)
{
// create ContentInfo
ContentInfo content = new ContentInfo(data);
// SignedCms represents signed data
SignedCms signedMessage = new SignedCms(content, detached:true)
// create a signer
CmsSigner signer = new CmsSigner(signingCert);
// sign the data
signedMessage.ComputeSignature(signer);
// create PKCS #7 byte array
byte[] signedBytes = signedMessage.Encode();
// return signed data
return signedBytes;
}
Exception when using ECC certificate + keys
System.Security.Cryptography.CryptographicException: Invalid provider type specified.
at System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer, Boolean silent)
at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer, Boolean silent)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer)
Creating the ECC Certificate
I am using the following batch file to generate my ECC Certificate(s), a representative snippet of which is
openssl ecparam -out test-ecparams.pem -name secp521r1
openssl req -newkey ec:test-ecparams.pem -sha512 -keyout test-key.pem -keyform PEM -out test-csr.pem -outform PEM -subj '/C=US/CN=ECC-cert-test'
openssl x509 -req -days 365 -in test-csr.pem -signkey test-key.pem -out test-cert.pem -sha512
openssl pkcs12 -export -aes256 -out test.pfx -in test-cert.pem -inkey test-key.pem -name "ECC-cert-test-friendlyname"
Extra Details
In case you don't want to (re)create the certificate per the above linked batch file, here is a dump of the certificate via
openssl asn1parse -in test-cert.pem -i -dump
0:d=0 hl=4 l= 450 cons: SEQUENCE
4:d=1 hl=4 l= 291 cons: SEQUENCE
8:d=2 hl=2 l= 9 prim: INTEGER :ECEA16A0348AEAE1
19:d=2 hl=2 l= 10 cons: SEQUENCE
21:d=3 hl=2 l= 8 prim: OBJECT :ecdsa-with-SHA512
31:d=2 hl=2 l= 37 cons: SEQUENCE
33:d=3 hl=2 l= 11 cons: SET
35:d=4 hl=2 l= 9 cons: SEQUENCE
37:d=5 hl=2 l= 3 prim: OBJECT :countryName
42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US
46:d=3 hl=2 l= 22 cons: SET
48:d=4 hl=2 l= 20 cons: SEQUENCE
50:d=5 hl=2 l= 3 prim: OBJECT :commonName
55:d=5 hl=2 l= 13 prim: UTF8STRING :ECC-cert-test
70:d=2 hl=2 l= 30 cons: SEQUENCE
72:d=3 hl=2 l= 13 prim: UTCTIME :130212015455Z
87:d=3 hl=2 l= 13 prim: UTCTIME :140212015455Z
102:d=2 hl=2 l= 37 cons: SEQUENCE
104:d=3 hl=2 l= 11 cons: SET
106:d=4 hl=2 l= 9 cons: SEQUENCE
108:d=5 hl=2 l= 3 prim: OBJECT :countryName
113:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US
117:d=3 hl=2 l= 22 cons: SET
119:d=4 hl=2 l= 20 cons: SEQUENCE
121:d=5 hl=2 l= 3 prim: OBJECT :commonName
126:d=5 hl=2 l= 13 prim: UTF8STRING :ECC-cert-test
141:d=2 hl=3 l= 155 cons: SEQUENCE
144:d=3 hl=2 l= 16 cons: SEQUENCE
146:d=4 hl=2 l= 7 prim: OBJECT :id-ecPublicKey
155:d=4 hl=2 l= 5 prim: OBJECT :secp521r1
162:d=3 hl=3 l= 134 prim: BIT STRING
0000 - 00 04 00 3b b5 16 53 81-4a e5 40 3e c3 43 6f 09 ...;..S.J.@>.Co.
0010 - 19 22 6f f2 45 81 71 41-3f 75 1e 89 74 a0 2a eb ."o.E.qA?u..t.*.
0020 - 8b d5 c5 1e 9c 50 6b 2e-2d 3c 69 da 5b 91 55 71 .....Pk.-<i.[.Uq
0030 - 46 8e ef a7 b2 13 ad e0-9c 26 6d 99 6b d3 42 e1 F........&m.k.B.
0040 - 3d 7a 21 2c 01 be 7b e8-43 c0 c0 79 ef 1e f4 4d =z!,..{.C..y...M
0050 - 7d 7d 52 56 30 17 57 2a-96 05 57 64 7d 8a e1 7a }}RV0.W*..Wd}..z
0060 - 3a 40 ff cd d6 03 e0 a2-00 3b 16 a9 26 91 d3 e9 :@.......;..&...
0070 - d2 d9 db 5e 7f 00 7a ba-61 d3 8b b5 9f c2 8e ba ...^..z.a.......
0080 - ef 16 e9 c6 b9 47 .....G
299:d=1 hl=2 l= 10 cons: SEQUENCE
301:d=2 hl=2 l= 8 prim: OBJECT :ecdsa-with-SHA512
311:d=1 hl=3 l= 140 prim: BIT STRING
0000 - 00 30 81 88 02 42 01 53-a8 eb 32 30 84 b6 80 ab .0...B.S..20....
0010 - 12 f2 03 2a fb 39 f6 3b-72 54 6e 1b 48 cd 52 0e ...*.9.;rTn.H.R.
0020 - a7 64 96 02 52 75 5d bc-5d 85 65 b1 a4 f1 05 1b .d..Ru].].e.....
0030 - 7b 9c 5d 7b e2 b3 21 88-f4 f3 d8 04 7f 45 68 ac {.]{..!......Eh.
0040 - f3 77 7a fa ff 12 17 fc-02 42 01 8f ab 6d 0a fb .wz......B...m..
0050 - dd 70 37 f4 53 03 91 13-97 63 3e 77 37 78 86 e4 .p7.S....c>w7x..
0060 - e7 4f 1c 06 51 99 2a e0-0b c1 6c ea 44 bd b2 41 .O..Q.*...l.D..A
0070 - 78 be 67 b6 00 74 fd b2-4d 11 2e a6 58 2e b5 02 x.g..t..M...X...
0080 - 77 ef 98 b2 ca be 68 b1-d3 27 e2 fb w.....h..'..
PS: I had previously asked a question trying to solve the problem in reverse; on doing ECC PKCS7/CMS via BouncyCastle but that got as many hugs as a cactus. This question pursues a much different approach...