我很难理解为什么我的简单C#SSL服务器代码失败了。当我尝试作为服务器进行身份验证时使用.p12文件我从文件系统加载,我收到错误。
这是我的代码:
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 2045);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(localEndPoint);
while (true)
{
server.Listen(10);
Socket client = server.Accept();
Stream clientStream = new NetworkStream(client, true);
var clientTlsStream = new SslStream(clientStream, false);
var p12Cert =
new X509Certificate2(
@"C:\Repos\ITEL-Trunk\Code\Applications\Server\bin\Debug\Configuration\Certificate_tool_signed_with_ca.p12",
"Passw0rd");
clientTlsStream.AuthenticateAsServer(p12Cert);
var cr = clientTlsStream.CanRead;
}
以下是例外情况:
System.ComponentModel.Win32Exception was unhandled
HResult=-2147467259
Message=The credentials supplied to the package were not recognized
Source=System
ErrorCode=-2147467259
NativeErrorCode=-2146893043
X509Certificate2对象表示'拥有私钥= true'我没有运气就试着像Admininstrator一样运行。我之前看到的其他SO问题围绕着CAPI权限,但由于我直接从文件系统加载,我无法应用这些答案。
答案 0 :(得分:2)
我能够将此问题追溯到生成p12文件的方式。 .p12是由一个基于Bouncy-Castle的C#实用程序创建的,该实用程序没有正确打包证书和私钥。我不得不更改证书生成器,以便正确打包证书和用于签名的CA证书。
在对证书生成器进行更改后,“无法识别提供给包的凭据”异常消失。
以下是似乎有效的P12打包器代码:
// Create the PKCS12 store
Pkcs12Store store = new Pkcs12Store();
// Add a Certificate entry
string certCn = cert.SubjectDN.GetValues(X509Name.CN).OfType<string>().Single();
X509CertificateEntry certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry(certCn, certEntry); // use DN as the Alias.
// Add a key entry & cert chain (if applicable)
AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(kp.Private);
X509CertificateEntry[] certChain;
if (_issuerCert != null)
{
X509CertificateEntry issuerCertEntry = new X509CertificateEntry(_issuerCert);
certChain = new X509CertificateEntry[] { certEntry, issuerCertEntry};
}
else
{
certChain = new X509CertificateEntry[] { certEntry };
}
store.SetKeyEntry(certCn, keyEntry, certChain); // Set the friendly name along with the generated certs key and its chain
// Write the p12 file to disk
FileInfo p12File = new FileInfo(pathToP12File);
Directory.CreateDirectory(p12File.DirectoryName);
using (FileStream filestream = new FileStream(pathToP12File, FileMode.Create, FileAccess.ReadWrite))
{
store.Save(filestream, password.ToCharArray(), new SecureRandom());
}