Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating X509Certificate2 from ECC X509Certificate throws 'System.NotSupportedException' in C#

I need to import ECC certificates into Windows Key Stores in C#. As the first step, I am using BouncyCastle to generate an EC key pair, create an X509 certificate with the public key, and sign it with the ECDSA and private key, i.e.,:

            var ecKeyPairGenerator = new ECKeyPairGenerator("ECDSA");
            ECKeyGenerationParameters ecKeyGenParams =
                new ECKeyGenerationParameters(SecObjectIdentifiers.SecP384r1, new SecureRandom());
            ecKeyPairGenerator.Init(ecKeyGenParams);
            AsymmetricCipherKeyPair pair = ecKeyPairGenerator.GenerateKeyPair();
            PrivateKeyInfo privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private);
            SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pair.Public);

            X509V3CertificateGenerator bcX509Gen = new X509V3CertificateGenerator();
// set cert fields
...
            bcX509Gen.SetPublicKey(pair.Public);
            Asn1SignatureFactory bcSigFactory =
                    new Asn1SignatureFactory(X9ObjectIdentifiers.ECDsaWithSha384.Id, pair.Private);
            X509Certificate bcCert = bcX509Gen.Generate(bcSigFactory);

Then, I create an X509Certificate2 with the certificate created above, i.e.,:

    SystemX509.X509Certificate2 msCert2 = 
        new SystemX509.X509Certificate2(bcCert.GetEncoded(), (string)null);

However, an exception is raised in creating the X509Certificate2:

'msCert2.PublicKey.Key' threw an exception of type 'System.NotSupportedException'
"The certificate key algorithm is not supported."

Using BC's DotNetUtilities.ToX509Certificate() results in the same exception.

I'm aware that the support for ECC certificates on Windows / .NET may not be complete, but my searches on the web seem to suggest that this should be possible? Any ideas what I'm doing wrong?

FYI, I'm using VS Community 2017, and my project has the target of .NET Framework 4.6.2.

Thanks!

like image 460
hyongsop Avatar asked Jul 14 '17 15:07

hyongsop


1 Answers

PublicKey.Key is unofficially deprecated (along with PrivateKey). It doesn't support ECC, and doesn't produce an RSA key that is capable of doing OAEP-SHA-2 encryption or DSA key capable of doing FIPS 186-3 DSA.

Instead you want to use the extension methods which don't require casting:

// GetECDsaPublicKey returns a unique object every call,
// so you're responsible for Disposing it (lest it end up on the Finalizer queue)
using (ECDsa ecdsa = msCert2.GetECDsaPublicKey())
{
    // do stuff with the public key object
}
like image 135
bartonjs Avatar answered Oct 16 '22 23:10

bartonjs