5

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!

hyongsop
  • 91
  • 2
  • 9

1 Answers1

6

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
}
bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • Ultimately, I'm trying to create PKCS12 and import it into the key store, similar to the goal in https://stackoverflow.com/questions/36624105/generate-certificate-using-ecdsa-in-c-sharp where you also provided very useful answers. Presently, tho., I find that the 'GetECDsaPublicKey() extension method is not available on 'msCert2' although I import `System.Security.Cryptography.X509Certificates` namespace, i.e.,: `using SystemX509 = System.Security.Cryptography.X509Certificates;` As a VS/.Net newbie, I must be doing something wrong? Thanks! – hyongsop Jul 14 '17 at 16:53
  • @hyongsop The extension method was added in 4.6.1. If you're getting a compile-time error check that you're actually referencing 4.6.2 and not just have it installed (VS seems fond of targeting older framework versions). – bartonjs Jul 14 '17 at 16:56
  • The project has ".NET Framework 4.6.2" as its target framework and has a reference to System.Security.dll in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Security.dll. Is there a VS-wide configuration I'm missing? – hyongsop Jul 14 '17 at 17:26
  • The extension methods are in System.Core.dll (which is usually automatically referenced) – bartonjs Jul 14 '17 at 17:27
  • The problem was the use of the alias in the `using` directive, i.e., `using SystemX509 = System.Security.Cryptography.X509Certificates` Without the alias, VS finds the method. Back to the original goal, is the P/Invoking still the only way to associate the private key with `msCert2` as per in your response to the question referenced above? Thanks. – hyongsop Jul 14 '17 at 17:55
  • If you are having the same problem as another question, why are you asking here instead of there? But the answer already says that the issue was fixed in 4.6.2. If you have a different problem (or symptom) perhaps ask another question... – bartonjs Jul 14 '17 at 18:01
  • I couldn't add comment there due to my status. Thanks for your help! – hyongsop Jul 14 '17 at 18:05