2014-06-05 33 views
1

我很難理解爲什麼我的簡單C#SSL服務器代碼失敗。當我嘗試使用從文件系統加載的.p12文件進行「身份驗證爲服務器」時,出現錯誤。簡單的C#SSL服務器:提供給包的憑證未被識別

這裏是我的代碼:

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對象表示 '已經私鑰=真正的',我已經試過作爲Admininstrator運行沒有運氣。其他我所見過的關於CAPI權限的SO問題,但是由於我直接從文件系統加載,所以我無法應用這些答案。

回答

1

我能夠將這個問題追溯回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()); 
}