导出或保存 CX509PrivateKey

Exporting or Saving CX509PrivateKey

是否可以通过某种方式保存或导出 CX509PrivateKey。我的想法是我创建一个发送给 CA 的 CSR 以获得证书然后......我必须以某种方式获得私钥但不知道如何,不幸的是在 google.

上找不到任何东西

我的一段代码:

var objPrivateKey = new CX509PrivateKey();
objPrivateKey.Length = int.Parse(ConfigurationManager.AppSettings["objPrivateKeyLength"]);
objPrivateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
objPrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
objPrivateKey.MachineContext = false;
objPrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
objPrivateKey.CspInformations = objCSPs;
objPrivateKey.Create();

其实我已经通过这种方式解决了这个任务。 (这里有更多的代码,所以你可以理解我想做什么)。

到此所有的工作都完成了。

/*
    using CERTADMINLib;
    using CERTCLILib;
    using CertSevAPI.Core.Models;
    using CertSrvAPI.Core;
    using CertSrvAPI.Core.Models;
    using Org.BouncyCastle.Asn1;
    using Org.BouncyCastle.Asn1.Pkcs;
    using Org.BouncyCastle.Asn1.X509;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Generators;
    using Org.BouncyCastle.Crypto.Prng;
    using Org.BouncyCastle.Pkcs;
    using Org.BouncyCastle.Security;
    using System;
*/

var caService = new CAService();

// Create a certificate request.
// The private key is here.
var caRequest = caService.CertRequest(subjectDN);

// Submit the certificate request and get the response.
var caResponse = caService.SendCertRequest(caRequest.Request);

// If certificated is not issued return null.
if (!caService.IsIssued(caResponse.Disposition))
{
    return null;
}

// Download the P7B file from CA.
var p7b = new WebClient().DownloadData(
    _appSettings.CERT_SRV + "/CertSrv/CertNew.p7b?ReqID=" + caResponse.CertRequest.GetRequestId() + "&Enc=bin");

try
{
    var certCollection = new X509Certificate2Collection();
    
    // Import the downloaded file.
    certCollection.Import(p7b);

    // Create a PKCS store.
    var pfx = new Pkcs12Store();
    
    // Insert root CA certificate into the PKCS store.
    pfx.SetCertificateEntry("rootCert",
        new X509CertificateEntry(DotNetUtilities.FromX509Certificate(certCollection[0])));

    // Get the second certificate from the downloaded file.
    // That one is the generated certificate for our request.
    var certificateEntry = new X509CertificateEntry[1];
    certificateEntry[0] = new X509CertificateEntry(DotNetUtilities.FromX509Certificate(certCollection[1]));
    
    // Insert our certificate with the private key
    // under the same alias so then we know that this private key
    // is for our certificate.
    pfx.SetKeyEntry("taxkey", new AsymmetricKeyEntry(caRequest.PrivateKey), certificateEntry);

    var memoryStream = new MemoryStream();
    
    // Stream PFX store using the desired password
    // for our file.
    pfx.Save(memoryStream, password.ToCharArray(), new SecureRandom());
   
    var pfxBytes = memoryStream.GetBuffer();
    pfxBytes = Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes, password.ToCharArray());

    // Here you can save the pfxBytes to a file, if you want.
    // Actually I needed it to give as a response in MVC application.
    return File(pfxBytes, System.Net.Mime.MediaTypeNames.Application.Octet, "NewCert.pfx");
}
catch (Exception ex)
{
    // If there is an error remove private key from
    // the memory.
    caRequest.PrivateKey = null;
    caRequest.Request = null;

    ErrorSignal.FromCurrentContext().Raise(ex);

    if (showError != null && showError.ToLower() == "true")
    {
        throw ex;
    }

    return null;
}

私钥在CARequest.

/*
    using Org.BouncyCastle.Crypto;
*/

public class CARequestModel
{
    public AsymmetricKeyParameter PrivateKey { get; set; }
    public string Request { get; set; }
}

私钥保存在内存中,直到我们需要它保存到PFX文件的那一刻,它是在我们创建证书请求的那一刻生成的。所以这里是证书请求生成方法。

public CARequestModel CertRequest(string subjectDN)
{
    var name = new X509Name(subjectDN);
    var rsaKeyPairGenerator = new RsaKeyPairGenerator();
    
    rsaKeyPairGenerator.Init(
        new KeyGenerationParameters(new SecureRandom(
                new CryptoApiRandomGenerator()), _appSettings.PRIVATE_KEY_LENGHT));

    // Generate key pair.
    var keyPair = rsaKeyPairGenerator.GenerateKeyPair();
    
    // Get the private key.
    var privateKey = keyPair.Private;
    
    // Get the public key.
    var publicKey = keyPair.Public;

    // Set the key usage scope.
    var keyUsage = new KeyUsage(KeyUsage.DigitalSignature);
    var extensionsGenerator = new X509ExtensionsGenerator();

    extensionsGenerator.AddExtension(X509Extensions.KeyUsage, true, keyUsage);

    var attribute = new AttributeX509(
        PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(extensionsGenerator.Generate()));

    // Create the certificate request
    var csr = new Pkcs10CertificationRequest("SHA256withRSA", name, publicKey, new DerSet(attribute), privateKey);
    
    // Get it as DER, because then I have to submit it to the MS CA server.
    var csrBytes = csr.GetDerEncoded();

    // Return the Request and private key
    return
        new CARequestModel
        {
            Request = Convert.ToBase64String(csrBytes),
            PrivateKey = privateKey
        };
}