pet*_*eay 25 c# security ssl bouncycastle certificate
我正在尝试使用BouncyCastle.Crypto dll创建证书,然后使用该证书将SslStream作为Windows服务进程中的服务器进行身份验证,该服务在本地系统帐户下运行.
然而,当我到达SslStream.AuthenticateAsServer(证书)调用,它抛出以"提供给包中的凭据无法识别"错误消息的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();
Run Code Online (Sandbox Code Playgroud)
好的,现在我已经创建并安装了证书.然后,我通过向其提供生成的证书的指纹来配置我的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);
Run Code Online (Sandbox Code Playgroud)
有谁知道这里的问题是什么?
如果我安装使用'makecert'创建的证书,但我不会遇到问题,但这不适用于生产证书.
我也尝试创建一个单独的x509v1 CA证书,然后采用X509v3服务器身份验证证书,但我得到了同样的错误,所以我在简单的示例代码移除了这个.
Jim*_*ood 45
该特定错误消息响铃.我猜你要么没有将私钥与证书一起存储,要么Windows服务无法访问私钥.要检查此问题,请打开"证书"MMC管理单元:
导航到证书,然后双击右窗格.在出现的"常规"选项卡上,您应该在底部看到一个小键图标以及文本"您有一个与此证书对应的私钥".如果没有,那就是问题所在.私钥未保存.
如果私钥是存在,单击确定关闭此对话框,然后在证书上在右窗格中单击鼠标右键,选择弹出菜单中:所有任务>管理私钥.在该对话框中,确保运行该服务的Windows帐户具有对私钥的读取权限.如果没有,那就是问题所在.
编辑:糟糕,您写道该服务作为本地系统运行,因此它必须是缺少私钥,如果它是这两个问题之一.无论如何,我会在我的答案中留下密钥访问检查,对于任何其他人来说,并且不是作为本地系统运行.
小智 13
有时,当应用程序尝试访问证书时没有足够的权限来访问证书时,问题可能通过以管理员身份运行应用程序来解决.
小智 12
我有同样的问题,尝试了许多帖子中的所有内容,并进行了谷歌研究。但看起来我找到了解决办法。当我将Identity从ApplicationPoolIdentity更改为LocalSystem 时,一切都开始完美运行。
可能会对某人有所帮助。
在网上找到了这个解决方案,但我找不到信用的来源.
由于我遇到了"提供给包的凭据无法识别"的问题,因为AuthenticateAsClient()(用于客户端验证),我想记录我是如何解决它的.这是一种具有相同目标的不同方法.因为它可能对AuthenticateAsServer()有用,所以不知道为什么不这样做.
在这里,我将BC证书转换为.NET证书.添加一个额外的步骤,将其转换为.NET X509Certificate2以存储它的PrivateKey属性.
Org.BouncyCastle.X509.X509Certificate bcCert;
X509Certificate dotNetCert = DotNetUtilities.ToX509Certificate(bcCert);
X509Certificate2 dotNetCert2 = new X509Certificate2(dotNetCert);
Run Code Online (Sandbox Code Playgroud)
将BouncyCastle私钥添加到.NET私钥时出现问题.X509证书转换正常但不是私钥.我使用提供的DotNetUtilities将BC私钥转换为RSACryptoServiceProvider.不幸的是,转换似乎并不完整.所以我创建了另一个RSACryptoServiceProvider,然后我进行了初始化.然后我将私钥导入到我创建的私钥中.
// Apparently, using DotNetUtilities to convert the private key is a little iffy. Have to do some init up front.
RSACryptoServiceProvider tempRcsp = (RSACryptoServiceProvider)DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)ackp.Private);
RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider(new CspParameters(1, "Microsoft Strong Cryptographic Provider",
new Guid().ToString(),
new CryptoKeySecurity(), null));
rcsp.ImportCspBlob(tempRcsp.ExportCspBlob(true));
dotNetCert2.PrivateKey = rcsp;
Run Code Online (Sandbox Code Playgroud)
之后,我能够将X509Certificate2对象直接保存到密钥库.我不需要实际的文件所以我跳过了那一步.
| 归档时间: |
|
| 查看次数: |
28606 次 |
| 最近记录: |