导出或保存CX509PrivateKey

时间:2015-05-04 20:46:21

标签: c# .net ssl ssl-certificate ca

是否有可能以某种方式保存或导出CX509PrivateKey。我的想法是,我创建了一个发送到CA的CSR获得证书然后......不知怎的,我必须得到私钥,但不知道如何,遗憾的是没有在谷歌上找到。

我的代码:

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();

1 个答案:

答案 0 :(得分:4)

实际上我已经用这种方式完成了这项任务(这里有更多的代码,所以你可以理解我的目的)。

这里完成了所有工作。

/*
    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("SHA1WITHRSA", 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
        };
}