SSL客户端证书 [英] SSL Client Certificates
本文介绍了SSL客户端证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在我的项目中遇到了麻烦,当我将客户端证书添加到我的请求(sslstream或httpwebrequest)中时,它们最终在请求的另一端为null.有人有什么想法吗?
代码示例:
公共 void RunClient()
{
字符串 machineName = " ;
字符串 serverName = " ;
// 从本地计算机上的商店获取客户端证书
xCert = PickCertificate(StoreLocation.LocalMachine,StoreName.My);
// 将证书加载到X509Certificate对象中.
var xCertColl = 新 X509CertificateCollection {xCert};
// 创建TCP/IP客户端套接字.
// machineName是运行服务器应用程序的主机.
TcpClient client = 新 TcpClient(machineName, 443 );
// Console.WriteLine(客户端已连接.");
// 创建将关闭客户端流的SSL流.
SslStream sslStream = 新 SslStream(
client.GetStream(),
真,
新 RemoteCertificateValidationCallback(ValidateServerCertificate),
空
);
// 服务器名称必须与服务器证书上的名称匹配.
尝试
{
sslStream.AuthenticateAsClient(serverName,新 X509CertificateCollection(xCertColl),SslProtocols.Tls, false );
}
捕获(AuthenticationException e)
{
Console.WriteLine(" ,e.Message);
如果(例如,InnerException!= 空)
{
Console.WriteLine(" ,例如e.InnerException.Message);
}
Console.WriteLine(" );
client.Close();
返回;
}
字节 []消息= Encoding.UTF8.GetBytes(" );
// 向服务器发送问候消息.
sslStream.Write(message);
sslStream.Flush();
StreamResponse = sslStream;
Image2.ImageUrl = WriteRequest();
// 从服务器读取消息.
// 字符串serverMessage = ReadMessage(sslStream);
// Console.WriteLine(服务器说:{0}",serverMessage);
// 关闭客户端连接.
client.Close();
Console.WriteLine(" );
}
私有 静态 X509Certificate2 PickCertificate(
StoreLocation位置,StoreName名称)
{
var store = 新 X509Store(名称,位置);
尝试
{
store.Open(OpenFlags.ReadOnly);
X509Certificate2证书;
如果(store.Certificates.Count == 1 )
cert = store.Certificates [ 0 ];
其他
{
// 从商店中选择证书
证书=
X509Certificate2UI.SelectFromCollection(
store.Certificates," ,
" ,X509SelectionFlag.SingleSelection)[ 0 ];
}
// 显示证书详细信息对话框
// X509Certificate2UI.DisplayCertificate(cert);
返回证书;
}
最终 {store.Close(); }
}
解决方案
已启用客户端证书:
http://www.microsoft.com. com/technet/prodtechnol/WindowsServer2003/Library/IIS/096519f4-3079-4571-9d28-8e5d286c5ab9.mspx?mfr = true [ http://support.microsoft.com/kb/901183 [ 使用系统; 使用 System.IO; 使用 System.Net; 使用使用System.Security.Cryptography.X509证书; 使用 System.Text; 公共 类 HttpWebRequestClientCertificateTest:ICertificatePolicy { 公共 布尔 CheckValidationResult(ServicePoint sp,X509证书, WebRequest请求, int 错误) { 返回 真; Windows无法识别// 服务器证书的CA. } 公共 无效 RunClient(字符串 certficatepath,字符串 password = 空) { 字符串主机= " ; 如果(参数长度> 0 ) host = args [ 0 ]; X509Certificate2证书= 空; 证书= 新 X509Certificate2(证书路径,密码); ServicePointManager.CertificatePolicy = 新 HttpWebRequestClientCertificateTest(); HttpWebRequest req =(HttpWebRequest)WebRequest.Create(主机); 如果(证书!= 空) req.ClientCertificates.Add(证书); Web响应响应; resp = req.GetResponse(); 流stream = resp.GetResponseStream(); StreamReader sr = 新 StreamReader(流,Encoding.UTF8); Console.WriteLine(sr.ReadToEnd()); } }
服务点管理器出现问题,在我尝试访问的服务器上证书不受信任.
>
I am having trouble with my project, when i add the client certificates to my requests (sslstream or httpwebrequest) they end up being null on the other end of the request. Does anyone have any ideas?
Code Sample:
public void RunClient()
{
string machineName = "my-loaner.myworld.local";
string serverName= "clientmachine";
//get the client certificate from the store on the local machine
xCert = PickCertificate(StoreLocation.LocalMachine, StoreName.My);
// Load the certificate into an X509Certificate object.
var xCertColl = new X509CertificateCollection {xCert};
// Create a TCP/IP client socket.
// machineName is the host running the server application.
TcpClient client = new TcpClient(machineName,443);
//Console.WriteLine("Client connected.");
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(
client.GetStream(),
true,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
// The server name must match the name on the server certificate.
try
{
sslStream.AuthenticateAsClient(serverName, new X509CertificateCollection(xCertColl), SslProtocols.Tls, false);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
byte[] messsage =Encoding.UTF8.GetBytes("GET /default.aspx?=23 HTTP/1.1\r\nHost: my-loaner.myworld.local\r\nAccept: */*\r\n\r\n");
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
StreamResponse = sslStream;
Image2.ImageUrl = WriteRequest();
// Read message from the server.
// string serverMessage = ReadMessage(sslStream);
//Console.WriteLine("Server says: {0}", serverMessage);
// Close the client connection.
client.Close();
Console.WriteLine("Client closed.");
}
private static X509Certificate2 PickCertificate(
StoreLocation location, StoreName name)
{
var store = new X509Store(name, location);
try
{
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert;
if(store.Certificates.Count == 1)
cert = store.Certificates[0];
else
{
// pick a certificate from the store
cert =
X509Certificate2UI.SelectFromCollection(
store.Certificates, "Caption",
"Message", X509SelectionFlag.SingleSelection)[0];
}
// show certificate details dialog
// X509Certificate2UI.DisplayCertificate(cert);
return cert;
}
finally { store.Close(); }
}
解决方案
Have you enabled client certificates:
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/096519f4-3079-4571-9d28-8e5d286c5ab9.mspx?mfr=true[^]
Some guide lines from MS:
http://support.microsoft.com/kb/901183[^]
Also look at the following code get some initial idea on ICertificatePolicy interface:
using System; using System.IO; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Text; public class HttpWebRequestClientCertificateTest : ICertificatePolicy { public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error) { return true; // server certificate's CA is not known to windows. } public void RunClient(string certficatepath, string password=null) { string host = "https://localhost:1234/"; if (args.Length > 0) host = args[0]; X509Certificate2 certificate = null; certificate = new X509Certificate2 (certficatepath, password); ServicePointManager.CertificatePolicy = new HttpWebRequestClientCertificateTest (); HttpWebRequest req = (HttpWebRequest) WebRequest.Create (host); if (certificate != null) req.ClientCertificates.Add (certificate); WebResponse resp = req.GetResponse (); Stream stream = resp.GetResponseStream (); StreamReader sr = new StreamReader (stream, Encoding.UTF8); Console.WriteLine (sr.ReadToEnd ()); } }
I had a problem with the service point manager where the certificate was not trusted on the server that I tried to access.
这篇关于SSL客户端证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文