如何使用BouncyCastle生成可用于WCF身份验证的X509Certificate2
本文关键字:WCF 身份验证 X509Certificate2 用于 何使用 BouncyCastle | 更新日期: 2023-09-27 18:24:17
这是我的WCF服务代码:
ServiceHost svh = new ServiceHost(typeof(MyClass));
var tcpbinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential, true);
//security
tcpbinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
svh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new BWUserNamePasswordValidator();
svh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =UserNamePasswordValidationMode.Custom;
svh.Credentials.ServiceCertificate.Certificate = GenerateCertificate(myCert);
svh.AddServiceEndpoint(typeof(IMyClass), tcpbinding, location);
svh.Open();
这是我用来生成证书的代码:
static X509Certificate2 GenerateCertificate(string certName)
{
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var keypair = keypairgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var CN = new X509Name("CN=" + certName);
var SN = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(SN);
gen.SetSubjectDN(CN);
gen.SetIssuerDN(CN);
gen.SetNotAfter(DateTime.MaxValue);
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(keypair.Public);
gen.AddExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(keypair.Public));
var newCert = gen.Generate(keypair.Private);
return new X509Certificate2(DotNetUtilities.ToX509Certificate((Org.BouncyCastle.X509.X509Certificate)newCert));
}
当我启动服务器时,它崩溃了,出现以下异常:
ArgumentException: It is likely that certificate 'CN=MyCert' may not
have a private key that is capable of key exchange or the process may not have
access rights for the private key. Please see inner exception for detail.
内部异常为null。
我做错了什么?
用于证书交换的密钥对需要为此明确创建。我认为你只需要向你的证书生成器添加另一个扩展,如下所示:
gen.AddExtension(
X509Extensions.KeyUsage,
true,
new KeyUsage(KeyUsage.keyCertSign));
不确定该语法是否完全正确,但这就是想法:您需要将证书中的密钥设置为用于证书签名,如果存在,这是一个"关键"扩展。