Chúng tôi đang cố gắng tạo chứng chỉ X509 (bao gồm cả khóa cá nhân) theo lập trình sử dụng thư viện C# và BouncyCastle. Chúng tôi đã thử sử dụng một số mã từ this sample by Felix Kollmann nhưng phần khóa cá nhân của chứng chỉ trả về giá trị rỗng. Mã và kiểm tra đơn vị như sau:Có thể tạo lập một chứng chỉ X509 bằng cách sử dụng chỉ C# không?
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace MyApp
{
public class CertificateGenerator
{
/// <summary>
///
/// </summary>
/// <remarks>Based on <see cref="http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx"/></remarks>
/// <param name="subjectName"></param>
/// <returns></returns>
public static byte[] GenerateCertificate(string subjectName)
{
var kpgen = new RsaKeyPairGenerator();
kpgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var kp = kpgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var certName = new X509Name("CN=" + subjectName);
var serialNo = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(serialNo);
gen.SetSubjectDN(certName);
gen.SetIssuerDN(certName);
gen.SetNotAfter(DateTime.Now.AddYears(100));
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(kp.Public);
gen.AddExtension(
X509Extensions.AuthorityKeyIdentifier.Id,
false,
new AuthorityKeyIdentifier(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public),
new GeneralNames(new GeneralName(certName)),
serialNo));
gen.AddExtension(
X509Extensions.ExtendedKeyUsage.Id,
false,
new ExtendedKeyUsage(new ArrayList() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") }));
var newCert = gen.Generate(kp.Private);
return DotNetUtilities.ToX509Certificate(newCert).Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "password");
}
}
}
Đơn vị kiểm tra:
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyApp
{
[TestClass]
public class CertificateGeneratorTests
{
[TestMethod]
public void GenerateCertificate_Test_ValidCertificate()
{
// Arrange
string subjectName = "test";
// Act
byte[] actual = CertificateGenerator.GenerateCertificate(subjectName);
// Assert
var cert = new X509Certificate2(actual, "password");
Assert.AreEqual("CN=" + subjectName, cert.Subject);
Assert.IsInstanceOfType(cert.PrivateKey, typeof(RSACryptoServiceProvider));
}
}
}
+1, Rất đẹp giải thích. Bạn đã xem thông số PKCS # 12 chưa? Đó là * BRUTAL *! Tôi nghĩ mọi thứ đều có thể xảy ra với PKCS # 12; bạn không cần phải có một khóa riêng. Thông thường, PKCS # 12 được sử dụng để giữ khóa riêng tư và chứng chỉ được liên kết nhưng có các khả năng khác. –
Liên kết được cung cấp cho bước 3 dường như không hoạt động. Rất may archive.org vẫn có nội dung: http://web.archive.org/web/20100504192226/http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx – Kyle
@Zenox, vui lòng chỉnh sửa câu trả lời của tôi và thay thế nó, điều này cũng sẽ cung cấp cho bạn một vài điểm. – Bruno