SSL客户端证书 [英] SSL Client Certificates

查看:187
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆