C# certutil.exe返回“;指定的网络密码不正确";
我正在使用Bouncy Castle库创建CA根证书和自签名机器证书,如下所示。我在下面列出了整个实现。我能够创建受密码保护的.PFX文件C# certutil.exe返回“;指定的网络密码不正确";,c#,x509certificate,bouncycastle,self-signed,certutil,C#,X509certificate,Bouncycastle,Self Signed,Certutil,我正在使用Bouncy Castle库创建CA根证书和自签名机器证书,如下所示。我在下面列出了整个实现。我能够创建受密码保护的.PFX文件 尽管我创建了CA根证书,但我没有安装它,因为它已经安装在计算机上(具有相同的主题和颁发者)。此外,我不确定原始的汽车根证书(MyCARoot.cer)是如何创建的,但它是通过以下命令安装的: certmgr.exe/add MyCARoot.cer/c/s/r localMachine root 在某些时候,我能够安装使用certutil.exe创建的自签名
- 我下面的实现是否正确-我是否遗漏了“允许私钥导出”或类似的内容
- 无论整个方法是否正确-我切换到它,因为我需要手动创建和安装自签名机器证书,而不是使用makecert.exe和pvk2pfx.exe,其中会提示用户4次输入私钥密码
- 如何验证生成的.pfx是否正确?(除了尝试使用certutil.exe安装它之外
AsymmetricKeyParameter caPrivateKey = null; try { // Create Root CA certificate X509Certificate2 x509 = CertMaker.GenerateCACertificate(mSubject, ref caPrivateKey); // Save certificate to file byte[] certBytes = x509.Export(X509ContentType.Cert, mRootCaPwd); string certFilePath = Path.Combine(mInstallPath, mSubject + ".cer"); File.WriteAllBytes(certFilePath, certBytes); } catch(Exception ex) { Log.Verbose(ex); TextLog.Info("Failed to generate CA Root Certificate"); return; } if (caPrivateKey == null) { Log.Verbose("Failed to generate CA Root Certificate: Failed to generate private key."); TextLog.Info("Failed to generate CA Root Certificate: Failed to generate private key."); return; } try { X509Certificate2 cert = CertMaker.GenerateSelfSignedCertificate(mSubject, mIssuer, caPrivateKey); // Save certificate to file byte[] certBytes = cert.Export(X509ContentType.Pkcs12, mComputerCertPwd); string filename = String.Format("MyServer_{0}.pfx", mSubject); string certFilePath = Path.Combine(mInstallPath, filename); File.WriteAllBytes(certFilePath, certBytes); } catch(Exception ex) { Log.Verbose("Failed to generate Machine Certificate." + ex.Message); TextLog.Info("Failed to generate Machine Certificate."); }
public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 4096)
{
using (Log.VerboseCall())
{
try
{
// Generating Random Numbers
var randomGenerator = new CryptoApiRandomGenerator();
var random = new SecureRandom(randomGenerator);
Log.Verbose("Generated Random Numbers");
ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);
Log.Verbose("Generated SignatureFactory");
// The Certificate Generator
var certificateGenerator = new X509V3CertificateGenerator();
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
// Serial Number
var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
Log.Verbose("Added Serial Number to CertificateGenerator");
// Issuer and Subject Name
X509Name subjectDN = new X509Name("CN=" + subjectName);
X509Name issuerDN = new X509Name("CN=" + issuerName);
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
Log.Verbose("Had set Subject Name and Issuer Name");
// Valid For
var notBefore = DateTime.UtcNow.Date;
var notAfter = notBefore.AddYears(100);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
// Subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
Log.Verbose("Had generated and set Subject Public Key");
// Generating the Certificate
var issuerKeyPair = subjectKeyPair;
// NOTE #1
// In another reference I saw this - instead
//var dotNetPrivateKey = ToDotNetKey(privateKey);
//var dotNetCert = new X509Certificate2(DotNetUtilities.ToX509Certificate(newCert));
//dotNetCert.PrivateKey = dotNetPrivateKey;
// self-signed certificate
var certificate = certificateGenerator.Generate(signatureFactory);
var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private);
Log.Verbose("Generated Certificate");
// correcponding private key
PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
Log.Verbose("Created Private Key");
// merge into X509Certificate2
var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
Log.Verbose("Generated Encoded Certificate");
var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());
if (seq.Count != 9)
throw new PemException("Malformed sequence in RSA private key");
RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(seq);
RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent,
rsa.PrivateExponent, rsa.Prime1,
rsa.Prime2, rsa.Exponent1,
rsa.Exponent2, rsa.Coefficient);
Log.Verbose("Generated RSA Key Parameters");
x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
Log.Verbose("Had set CA Private Key");
return x509;
}
catch (Exception ex)
{
Console.WriteLine("Failed to create Self-Signed Machine certificate: {0}", ex.Message);
return null;
}
}
}
/// <summary>
/// Generate Self-Signed Root CA Certificate
/// </summary>
/// <param name="subjectName"></param>
/// <param name="CaPrivateKey"></param>
/// <returns>Returns the X509 certificate and reference to Root CA Private Key</returns>
public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
{
using (Log.VerboseCall())
{
try
{
int keyStrength = 4096;
// Generating Random Numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
Log.Verbose("Generated Random Numbers");
// The Certificate Generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
// Serial Number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
Log.Verbose("Added Serial Number to CertificateGenerator");
// Issuer and Subject Name
X509Name subjectDN = new X509Name("CN="+subjectName);
X509Name issuerDN = subjectDN;
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
Log.Verbose("Had set Subject Name and Issuer Name");
// Valid For
var notBefore = DateTime.UtcNow.Date;
var notAfter = notBefore.AddYears(100);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
// Subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
Log.Verbose("Had generated and set Subject Public Key");
// Generating the Certificate
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);
Log.Verbose("Created SignatureFactory");
// selfsign certificate
// certificateGenerator.Generate signs the certificate using the private key,
// but doesn't put the private key in the certificate, which wouldn't make sense.
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
Log.Verbose("Generated CA Root Certificate");
CaPrivateKey = issuerKeyPair.Private;
Log.Verbose("Had set CA Private Key");
return x509;
}
catch (Exception ex)
{
Log.VerboseFormat("Failed to create Root CA certificate: {0}", ex.Message);
return null;
}
}
}
/// <summary>
/// See NOTE #1
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
{
// If you don't do this (cspParams), when you execute the netsh command you get the error 1312. i.e. of the netsh command:
//
// netsh http add sslcert ipport = 192.168.0.15:8081 certhash =5424476237fc2785ed2d0fd620a9131d7c999f6f appid = { 02639d71 - 0935 - 35e8 - 9d1b - 9dd1a2a34627 }
var cspParams = new CspParameters
{
KeyContainerName = Guid.NewGuid().ToString(),
KeyNumber = (int)KeyNumber.Exchange,
Flags = CspProviderFlags.UseMachineKeyStore
};
var rsaProvider = new RSACryptoServiceProvider(cspParams);
var parameters = new RSAParameters
{
Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
P = privateKey.P.ToByteArrayUnsigned(),
Q = privateKey.Q.ToByteArrayUnsigned(),
DP = privateKey.DP.ToByteArrayUnsigned(),
DQ = privateKey.DQ.ToByteArrayUnsigned(),
InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
D = privateKey.Exponent.ToByteArrayUnsigned(),
Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
};
rsaProvider.ImportParameters(parameters);
return rsaProvider;
}
public static X509Certificate2 GenerateSelfSignedCertificate(字符串subjectName、字符串issuerName、AsymmetricKeyParameter issuerPrivKey、int-keyStrength=4096)
{
使用(Log.VerboseCall())
{
尝试
{
//生成随机数
var randomGenerator=新的CryptoApiranomGenerator();
var random=新的SecureRandom(随机生成器);
详细(“生成的随机数”);
ISignatureFactory signatureFactory=新的ASN1 signatureFactory(“SHA512 with RSA”,issuerPrivKey,随机);
详细(“生成的SignatureFactory”);
//证书生成器
var certificateGenerator=新X509V3CertificateGenerator();
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id,true,新的ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
//序列号
var serialNumber=bigingers.CreateRandomInRange(biginger.One,biginger.ValueOf(Int64.MaxValue),random);
证书生成器。设置序列号(序列号);
详细(“将序列号添加到CertificateGenerator”);
//发行人和主题名称
X509Name subjectDN=新的X509Name(“CN=“+subjectName”);
X509Name issuerDN=新的X509Name(“CN=“+issuerName”);
certificateGenerator.SetIssuerDN(发行人N);
certificateGenerator.SetSubjectDN(subjectDN);
详细(“已设置主题名称和发行人名称”);
//适用于
var notBefore=DateTime.UtcNow.Date;
var notAfter=notBefore.AddYears(100);
证书生成器。SetNotBefore(notBefore);
证书生成器。SetNotAfter(notAfter);
//主题公钥
非对称密码密钥对主体密钥对;
var keyGenerationParameters=新的keyGenerationParameters(随机、keyStrength);
var keyPairGenerator=new rsakypairgenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair=keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
Verbose(“已生成并设置主题公钥”);
//生成证书
var issuerKeyPair=主题密钥对;
//注#1
//在另一篇参考文章中,我看到了这一点——相反
//var dotNetPrivateKey=ToDotNetKey(privateKey);
//var dotNetCert=newx509certificate2(DotNetUtilities.ToX509Certificate(newCert));
//dotNetCert.PrivateKey=dotNetPrivateKey;
//自签名证书
var certificate=certificateGenerator.Generate(signatureFactory);
var dotNetPrivateKey=ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private);
详细日志(“生成的证书”);
//相应的私钥
PrivateKeyInfo=PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
详细(“创建的私钥”);
//合并到X509Certificate2中
var x509=new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
详细(“生成的编码证书”);
var seq=(Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().getDeRecoded());
如果(序号!=9)
抛出新的异常(“RSA私钥中的错误序列”);
RsaPrivateKeyStructure rsa=RsaPrivateKeyStructure.GetInstance(seq);
RsaPrivateCrtKeyParameters rsaparms=新的RsaPrivateCrtKeyParameters(rsa.modules,rsa.PublicExponent,
rsa.PrivateExponent,rsa.Prime1,
rsa.Prime2,rsa.Exponent1,
rsa.指数2,rsa.系数);
Verbose(“生成的RSA密钥参数”);
x509.PrivateKey=DotNetUtilities.ToRSA(rsaparms);
Verbose(“已设置CA私钥”);
返回x50