Create CSR from CngKey or X509Certificate instance (2)

I need to create a certificate signing request file to submit to a third party.

I am clearly lacking in knowledge that prevents me from making a cognitive leap from objects CngKey

and / or X509Certificate2

that I have successfully created and a request to sign an ASN.1 / DER certificate in Base64.

All searches I've done for c# generate csr

(and equivalents) will tell me how to generate a self-signed certificate. However, I don't think this is exactly what I need (or is it?).

The object CngKey

is created using the private key generated by the hardware security module, thus:

var parameters = new CngKeyCreationParameters
{
    Provider = "The HSM ECDSA Provider",
    ExportPolicy = CngExportPolicies.AllowArchiving,
    KeyCreationOptions = CngKeyCreationOptions.None,
    KeyUsage = CngKeyUsages.Signing,
    UIPolicy = new CngUIPolicy(CngUIProtectionLevels.ForceHighProtection)
};
var key = CngKey.Create(CngAlgorithm.ECDsaP256, keyName, parameters);

      

Using extensions System.Cryptography

from http://clrsecurity.codeplex.com/ I can generate a self-signed certificate:

var dn = new X500DistinguishedName("CN=MyCompany;OU=MyOrgUnit;OID.2.25.4.45=MyUniqueID");

var certParams = new X509CertificateCreationParameters(dn)
{
    SignatureAlgorithm = X509CertificateSignatureAlgorithm.ECDsaSha256,
};

var cert = key.CreateSelfSignedCertificate(certParams);

      

I can even store it in the certificate enrollment request store:

var store = new X509Store("REQUEST", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();

      

However, from there I got stuck.

I tried Convert.ToBase64String(cert.Export(X509ContentType.Cert))

(and other values X509ContentType

) but they don't seem to be valid (my smoke tests with using openssl req

cause a bunch of ASN.1 errors).

Having received this, I would prefer not to rewrite with a third party library like BouncyCastle or OpenSSL.NET, partly due to lack of documentation, partly due to interoperability with HSM. Likewise, I cannot export the private key from the HSM (because what would the point of the HSM be if I could?).

I would just use regular Windows MMC certificates if I could, but I need to provide an ASN.1 BIT STRING as part of the topic (I've excluded generating this from the above for brevity) and I can't do it with the standard Create Custom Request dialog.

However, this dialog can create the desired CSR file format, so the functionality must exist somewhere, even if it looks like the Win32 API.

So this:

  • Generating a private key
  • Generate certificate from key
  • Store certificate
  • ???
  • Send CSR to third parties
  • Profit.

So what exactly am I missing ...?

+3


source to share


1 answer


CSR is a Certificate Signing Request. It contains the public key and any metadata that you want your certificate to contain. A third party (usually a Certification Authority such as a CA) then creates a certificate and provides you with the certificate. So your order is wrong.

  • Create a private key
  • Generate CSR
  • Send CSR to third parties
  • Get a certificate from a third party

CSR is usually provided in PKCS # 10 format to third party / CA. It takes a lot of work to create ASN.1 / DER for CSR if you really want to write this part yourself. RFC2986 provides the exact specifications for creating CSRs.



Since your script includes HSM and the CSR needs to be signed, you will need to use your Cng provider to include the signature in the CSR.

There are no APIs in .Net (or Win32 crypto / bcrypt) that will allow you to "just call a function" and get the CSR for you.

Also note that the CSR contains what you are asking for in your certificate. The CA can change or omit any information that you provide to be included in the certificate.

+1


source







All Articles