DeepSpace101
DeepSpace101

Reputation: 13752

What ECC certificate would work with the following PKCS7/CMS code?

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...

Upvotes: 5

Views: 3088

Answers (3)

Devvy
Devvy

Reputation: 45

First of all, PKCS#7 and Cryptographic Message Syntax (CMS) work differently in terms of signature algorithm OIDs.

In an X.509 certificate, the certificate's signature comes with an OID that is a combination of an (asymmetric) encryption scheme and a message digest algorithm. Examples are:

  • sha256WithRsaEncryption (RSA for md encryption, SHA2-256 for hashing);
  • ecdsaWithSha256 (ECDSA for md encryption, SHA2-256 for hashing);
  • (...).

This works differently in PKCS#7 (aka CMS): The md encryption algorithm OID is separated from the pure hash scheme, i.e. an authenticatedAttribute is part of the PKCS#7 signature, which states the hash algorithm.

Apart from that, a message digest encryption algorithm is specified, which can be one of:

  • rsaEncryption (PKCS#1 v1.5);
  • rsaPss (PKCS#1 PSS signatures);
  • ecPublicKey + namedCurve OID (for ECDSA);
  • id-EdDSAPublicKey + either id-Curve25519 or id-Curve448 (for EdDSA).

To make a long story short: Your X.509 signing certificate comes in your case with an EC key pair (curve, e.g. secp256r1, secp384r1, secp521r1, ...) - the public EC key is part of your X.509 certificate (namedCurve OID scheme).

You select a hashing scheme (e.g. SHA2-256, SHA2-384, SHA2-512). You specify in PKCS#7 the md encryption algorithm as explained above, you hash your content using your selected message digest algorithm putting this into the PKCS#7 authenticated attribute.

Upvotes: 0

Viktor Dukhovni
Viktor Dukhovni

Reputation: 11

It may be worth noting that TLS ciphersuites are not very related to CMS (note that the RFC for CMS has no mentions of TLS), so if your intention is to use CMS, then looking at the list of TLS ciphersuites that OpenSSL supports may not be the right place to look.

Also, as there is no SHA-128, using ecdsa-with-SHA128 appears to be quite the feat. ecdsa-with-SHA256 might actually be a better place to start.

Upvotes: 1

Tobi
Tobi

Reputation: 161

Your combination: ecdsa-with-SHA512 is not the best idea :-) Try ecdsa-with-SHA128 instead. If it works, you may increase to ecdsa-with-SHA256.

Hove you already checked the MSDN Blog on Elliptic Curve Diffie-Hellman?

You should consider not using the .NET default crypto libs; better try using OpenSSL and the .NET / OpenSSL Wrapper.

In Detail: OpenSSL provides a list of cyphers: Open SSL ECC TLS 1.2 Cyphers: - TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ECDH-ECDSA-AES128-SHA256 - TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ECDH-ECDSA-AES256-SHA384 - TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 ECDH-ECDSA-AES128-GCM-SHA256 - TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 ECDH-ECDSA-AES256-GCM-SHA384

The list changes if you choose TLS 1.1!

.NET 4.5 Cyphers: A bit hidden, and the list is not independent from your operating system libs: Check out the class, and the attributes of the Elliptic Curve Digital Signature Algorithm (ECDSA) class: MSDN ECDSA

So now just choose a working combination.

Upvotes: -1

Related Questions