We are generating some self-signed certificates for testing using BouncyCastle, but the code throws an exception when we try to add a private key to the certificate. Here's the code in question:
private static X509Certificate2 CreateCertificate(string subject, DateTimeOffset notBefore, DataTimeOffset notAfter, string issuer, AsymmetricKeyParamter issuerPrivateKey)
{
// Setup
X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
SecureRandom random = new SecureRandom(new CryptoApiRandomGenerator());
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(new KeyGenerationParameters(random, KeyStrength));
// Randomly generate a serial number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
certGenerator.SetSerialNumber(serialNumber);
// Set the issuer and subject names
X509Name issuerName = new X509Name(issuer);
X509Name subjectName = new X509Name(subject);
certGenerator.SetIssuerDN(issuerName);
certGenerator.SetSubjectDN(subjectName);
// Set the validity period
certGenerator.SetNotBefore(notBefore.UtcDateTime);
certGenerator.SetNotAfter(notAfter.UtcDateTime);
// Randomly generate the public key
AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certGenerator.SetPublicKey(subjectKeyPair.Public);
// Generate the signed certificate
ISignatureFactory signatureFactory = new Asn1SignatureFactory(SHA256RSASignatureAlgorithm, issuerPrivateKey ?? subjectKeyPair.Private, random);
X509Certificate2 certificate = new X509Certificate2(certGenerator.Generate(signatureFactory).GetEncoded());
// Include the private key with the response
// ERROR HERE!
certificate.PrivateKey = DotNetUtilities.ToRSA(subjectKeyPair.Private as RsaPrivateCrtKeyParameters);
return certificate;
}
This code is in a library that targets .NET Standard 2.0, and the library is a dependency of two different applications: one targeting .NET Core 2.1 and the other targeting .NET Framework 4.7.2. I believe this works fine in the .NET Framework app, but in the .NET Core app I'm getting an exception with this message on the indicated line above:
Operation is not supported on this platform.
Apparently this is expected behavior in .NET Core. I am aware of the CopyWithPrivateKey
method as mentioned in this question, which in theory is what I should be using. However, this method is not supported in .NET Standard 2.0 (note the error at the top of the page indicating the redirect). Furthermore, the .NET Framework app cannot be converted to .NET Core at the moment because of some other dependencies which are .NET Framework. According to this matrix, .NET Standard 2.1 is not supported by .NET Framework at all, which means I cannot upgrade to .NET Standard 2.1 and use CopyWithPrivateKey
!
How can I create an X509Certificate2
with a private key in .NET Standard 2.0 in a way that's compatible with .NET Core?