【发布时间】:2017-05-07 23:16:42
【问题描述】:
因此,您将在下面找到我的代码,该代码使用其中的私钥创建自签名证书。它存储在用户存储中。现在当我使用 mmc 工具时,我可以从证书中导出私钥吗?我认为这是您在创建证书时必须明确添加的标志?
所以我想知道的是,如何更改此代码,使私钥不再可通过 mmc 导出。
代码:
public static X509Certificate2 GenerateSelfSignedCertificateNoCA(string subjectName, string issuerName)
{
const int keyStrength = 2048;
// Generating Random Numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
// The Certificate Generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
// Serial Number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
// Signature Algorithm
const string signatureAlgorithm = "SHA256WithRSA";
certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
// Issuer and Subject Name
X509Name subjectDN = new X509Name(subjectName);
X509Name issuerDN = new X509Name(issuerName);
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
// Valid For
DateTime notBefore = DateTime.UtcNow.Date;
DateTime notAfter = notBefore.AddYears(2);
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);
// Generating the Certificate
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
// selfsign certificate
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(subjectKeyPair.Private, random);
// correcponding private key
PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
// merge into X509Certificate2
X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());
if (seq.Count != 9)
{
//throw new PemException("malformed sequence in RSA private key");
}
RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);
RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);
x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
// Console.Write("Private key: " + x509.PrivateKey);
return x509;
}
【问题讨论】:
-
X509KeyStorageFlags.Exportable msdn.microsoft.com/en-us/library/…
-
是的,我知道它就在那里,只有在你想明确地将私钥设置为可导出时才使用它。不是反过来。如您所见,我没有使用它。
-
一切只依赖于软件的东西都很容易提取,即使它不能导出,你也可以等待你的程序使用它,然后内存转储它,或者其他什么。根据我的经验,如果您想安全起见,请使用 codemeter 加上 codeencryption/obfuscation 之类的东西。它并非不可破解,但几乎在所有情况下都不值得付出努力。
-
是的,我很痛苦地意识到这一点,问题是我们的客户很难按下“使其不可导出”部分。因此,我们尽力满足并给他们一种安全感。
-
我将尝试根据这篇文章重新实现创建自签名证书的方法:stackoverflow.com/questions/13806299/… - 有了这个库,我可以明确设置“不可导出”
标签: c# x509certificate x509certificate2