【发布时间】:2019-04-03 13:13:00
【问题描述】:
我需要一些帮助来使用 bouncycastle 生成 PKCS12 pfx 文件。
我正在使用休闲命令来生成 PKCS12 pfx 文件:
keytool -genkey -storetype PKCS12 -dname "CN=%CN, OU=%OU, O=Company, L=City, ST=State, C=US" -alias clientcert -keyalg RSA -keysize 2048 -keystore %keystore_name% -storepass %default_keystore_pwd% -keypass %default_keystore_pwd%
以 root 身份导入 ca.crt:
keytool -import -trustcacerts -noprompt -alias root -file ca.crt -keystore %keystore_name% -storepass %default_keystore_pwd%
ca.crt 是用于签署生成的 CSR 的根证书
keytool -certreq -alias clientcert -keystore %keystore_name% -file clientcert.csr -keypass %default_keystore_pwd% -storepass %default_keystore_pwd%
此时,我获得了 CSR,我使用 ca.crt
在专用服务器上签名然后我将签名证书导入 pfx:
keytool -import -alias clientcert -file signed.crt -keystore %keystore_name% -storepass %default_keystore_pwd% -keypass %default_keystore_pwd%
我正在使用 bouncycastle 库创建 CSR 和私钥。然后我用 ca.crt 在服务器上签署 CSR。
最终文件夹中有3个文件:
- ca.crt
- signed.crt - 用 ca.crt 签名的证书
- private_key.key(未加密的 RSA 密钥)
使用我之前提供的命令,最终的 pfx 文件在提取时如下所示:
keytool -list -rfc -keystore client_keystore.pfx
Enter keystore password:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 2 entries
Alias name: clientcert
Creation date: Mar 22, 2019
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
-----BEGIN CERTIFICATE-----
//removed
-----END CERTIFICATE-----
Certificate[2]:
-----BEGIN CERTIFICATE-----
//removed
-----END CERTIFICATE-----
*******************************************
*******************************************
Alias name: root
Creation date: Apr 3, 2019
Entry type: trustedCertEntry
-----BEGIN CERTIFICATE-----
//removed
-----END CERTIFICATE-----
*******************************************
*******************************************
我已经签署了 ca.crt、certificate.crt 和 private.key。 如何使用 bouncycastle 库创建相同结构的 pfx 文件?
生成 CSR 和密钥:
public void TDE(string CName, string OUnit, string Country, string State, string City, string EmailAdr, string password)
{
AsymmetricCipherKeyPair pair;
Pkcs10CertificationRequest csr;
Asn1SignatureFactory signatureFactory;
var random = new SecureRandom(new CryptoApiRandomGenerator());
var values = new Dictionary<DerObjectIdentifier, string>
{
{X509Name.CN, CName},
{X509Name.OU, OUnit},
{X509Name.O, "Company"},
{X509Name.L, City},
{X509Name.ST, State},
{X509Name.C, Country},
{X509Name.EmailAddress, EmailAdr },
};
var extensions = new Dictionary<DerObjectIdentifier, X509Extension>()
{
{X509Extensions.BasicConstraints, new X509Extension(true, new DerOctetString(new BasicConstraints(false)))},
{X509Extensions.KeyUsage, new X509Extension(true, new DerOctetString(new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment | KeyUsage.DataEncipherment | KeyUsage.NonRepudiation)))},
{X509Extensions.ExtendedKeyUsage, new X509Extension(false, new DerOctetString(new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth)))},
};
var subject = new X509Name(values.Keys.Reverse().ToList(), values);
var gen = new RsaKeyPairGenerator();
gen.Init(new KeyGenerationParameters(random, 2048));
pair = gen.GenerateKeyPair();
signatureFactory = new Asn1SignatureFactory("SHA256withRSA", pair.Private);
extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(false, new DerOctetString(new SubjectKeyIdentifierStructure(pair.Public))));
csr = new Pkcs10CertificationRequest(signatureFactory, subject, pair.Public, new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new X509Extensions(extensions)))), pair.Private);
//Convert BouncyCastle csr to .PEM file.
var csrPem = new StringBuilder();
var csrPemWriter = new PemWriter(new StringWriter(csrPem));
csrPemWriter.WriteObject(csr);
csrPemWriter.Writer.Flush();
//Writes password to file
Directory.CreateDirectory(Environment.CurrentDirectory + "\\" + CName + "_" + OUnit);
File.AppendAllText(Environment.CurrentDirectory + "\\" + CName + "_" + OUnit + "\\key_password.txt", password);
//writes CSR to file
File.AppendAllText(Environment.CurrentDirectory + "\\" + CName + "_" + OUnit + "\\" + CName + "_csr", csrPem.ToString());
//Convert BouncyCastle Private Key to .PEM file.
var privateKeyPem = new StringBuilder();
var privateKeyPemWriter = new PemWriter(new StringWriter(privateKeyPem));
privateKeyPemWriter.WriteObject(pair.Private);
privateKeyPemWriter.Writer.Flush();
//privateKeyPem.ToString();
File.AppendAllText(Environment.CurrentDirectory + "\\" + CName + "_" + OUnit + "\\" + CName + "_" + OUnit + "_prvNE.key", privateKeyPem.ToString());
}
谢谢
【问题讨论】:
标签: c# .net cryptography bouncycastle pkcs#12