C# &引用;提供给包的凭据未被识别”;使用使用BouncyCastle生成的证书作为服务器进行身份验证时出错
我正在尝试使用BouncyCastle.Crypto dll创建一个证书,然后使用该dll将SslStream作为Windows服务进程中的服务器进行身份验证,该进程在本地系统帐户下运行 但是,当我访问SslStream.authenticatesServer(certificate)调用时,它抛出一个Win32异常,错误消息为“提供给包的凭据未被识别” 关于这个错误消息,这里有几个问题,但没有一个能够描述或解决我的特定问题 为了希望有人能够提供一些帮助,我提供了用于创建和安装证书的代码:C# &引用;提供给包的凭据未被识别”;使用使用BouncyCastle生成的证书作为服务器进行身份验证时出错,c#,security,ssl,certificate,bouncycastle,C#,Security,Ssl,Certificate,Bouncycastle,我正在尝试使用BouncyCastle.Crypto dll创建一个证书,然后使用该dll将SslStream作为Windows服务进程中的服务器进行身份验证,该进程在本地系统帐户下运行 但是,当我访问SslStream.authenticatesServer(certificate)调用时,它抛出一个Win32异常,错误消息为“提供给包的凭据未被识别” 关于这个错误消息,这里有几个问题,但没有一个能够描述或解决我的特定问题 为了希望有人能够提供一些帮助,我提供了用于创建和安装证书的代码: //
// First create a certificate using the BouncyCastle classes
BigInteger serialNumber = BigInteger.ProbablePrime(120, new Random());
AsymmetricCipherKeyPair keyPair = GenerateKeyPair();
X509V1CertificateGenerator generator = new X509V1CertificateGenerator();
generator.SetSerialNumber(serialNumber);
generator.SetIssuerDN(new X509Name("CN=My Issuer"));
generator.SetNotBefore(DateTime.Today);
generator.SetNotAfter(DateTime.Today.AddYears(100));
generator.SetSubjectDN(new X509Name("CN=My Issuer"));
generator.SetPublicKey(keyPair.Public);
generator.SetSignatureAlgorithm("SHA1WITHRSA");
Org.BouncyCastle.X509.X509Certificate cert = generator.Generate(
keyPair.Private, SecureRandom.GetInstance("SHA1PRNG"));
// Ok, now we have a BouncyCastle certificate, we need to convert it to the
// System.Security.Cryptography class, by writing it out to disk and reloading
X509Certificate2 dotNetCert;
string tempStorePassword = "Password01"; // In real life I'd use a random password
FileInfo tempStoreFile = new FileInfo(Path.GetTempFileName());
try
{
Pkcs12Store newStore = new Pkcs12Store();
X509CertificateEntry entry = new X509CertificateEntry(cert);
newStore.SetCertificateEntry(Environment.MachineName, entry);
newStore.SetKeyEntry(
Environment.MachineName,
new AsymmetricKeyEntry(keyPair.Private),
new [] { entry });
using (FileStream s = tempStoreFile.Create())
{
newStore.Save(s,
tempStorePassword.ToCharArray(),
new SecureRandom(new CryptoApiRandomGenerator()));
}
// Reload the certificate from disk
dotNetCert = new X509Certificate2(tempStoreFile.FullName, tempStorePassword);
}
finally
{
tempStoreFile.Delete();
}
// Now install it into the required certificate stores
X509Store targetStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
targetStore.Open(OpenFlags.ReadWrite);
targetStore.Add(dotNetCert);
targetStore.Close();
好的,现在我已经创建并安装了证书。然后,通过向Windows服务提供生成的证书指纹,将其配置为使用此证书。然后,我使用如下证书:
// First load the certificate
X509Certificate2 certificate = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 certInStore in store.Certificates)
{
if (certInStore.Thumbprint == "...value not shown...")
{
certificate = certInStore;
break;
}
}
SslStream sslStream = new SslStream(new NetworkStream(socket, false), false);
// Now this line throws a Win32Exception
// "The credentials supplied to the package were not recognized"
sslStream.AuthenticateAsServer(certificate);
有人知道这里可能有什么问题吗
如果安装使用“makecert”创建的证书,我不会遇到问题,但这不适用于生产证书
我还尝试创建一个单独的x509v1 CA证书,然后创建x509v3证书用于服务器身份验证,但我得到了相同的错误,因此为了简单起见,我在示例代码中删除了此错误。我不记得此错误,但您创建的证书不是用于SSL/TLS的有效证书,包括:
- v1(非v3)证书李>
- 缺少扩展李>
- 无效CN李>
makecert
生成的证书更合适(但最后一个证书可以生成可用于SSL/TLS服务器证书的最小集)
我强烈建议您从知名的证书颁发机构(CA)购买用于生产的SSL/TLS证书。这将获得大多数浏览器和工具都能识别的工作证书。这条特定的错误消息敲响了警钟。我猜您没有将私钥与证书一起存储,或者Windows服务没有访问私钥的权限。要检查此问题,请打开证书MMC管理单元:
Org.bounchycastle.X509.X509证书bcCert;
X509CertificateDotNetCert=DotNetUtilities.ToX509Certificate(bcCert);
X509Certificate2 dotNetCert2=新的X509Certificate2(dotNetCert);
将BouncyCastle私钥添加到.NET私钥时出现问题。X509证书可以正常转换,但不是私钥。我使用提供的DotNetUtilities将BC私钥转换为RSACryptoServiceProvider。不幸的是,转换似乎没有完成。因此,我创建了另一个RSACryptServiceProvider,然后对其进行了初始化。然后我将私钥导入到我创建的私钥中
//显然,使用DotNetUtilities转换私钥有点不确定。我得先做些准备。
rsacyptoserviceprovider tempRcsp=(rsacyptoserviceprovider)DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)ackp.Private);
RSACryptoServiceProvider rcsp=新的RSACryptoServiceProvider(新的csp参数(1,“Microsoft强加密提供程序”,
新Guid().ToString(),
新的CryptoKeySecurity(),null));
rcsp.ImportCspBlob(tempRcsp.ExportCspBlob(true));
dotNetCert2.PrivateKey=rcsp;
之后,我能够将X509Certificate2对象直接保存到密钥存储。我不需要实际文件,因此跳过了该步骤。当应用程序尝试访问证书时,如果没有足够的权限访问证书,则问题可能会通过以管理员身份运行应用程序来解决。以前,每次遇到此问题,我不得不从本地机器证书存储中删除证书并重新导入。然后一切看起来都很幸福。我看不出如果只是重新导入它就可以解决问题,那么它怎么可能是一个全局权限问题或无效证书 我最终是如何使用
"C:\Program Files (x86)\Windows Resource Kits\Tools\winhttpcertcfg" -i cert.p12 -c LOCAL_MACHINE\My -a UserWhoUsesTheCert -p passwordforp12