https证书

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using Imps.Services.Common;
using Imps.Services.MMSAdapterCommon;
using Imps.Services.MMSAdapter.Common;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

 

public class HttpsRequest

{

   public static void Initialize()

{

   if(isClientCer)
            {
                //挂接验证服务端证书的回调
                ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
            }

}

 

protected static void ProcessRequest(string uri,string body)

{

     byte[] buffer = System.Text.Encoding.UTF8.GetBytes(body);
                System.Net.HttpWebRequest webReq = System.Net.HttpWebRequest.Create(url) as HttpWebRequest;
                webReq.Method = "POST";
                if (isCer)
                {

                   //需要Https验证
                    System.Security.Cryptography.X509Certificates.X509Certificate cer;
                    //System.Security.Cryptography.X509Certificates.X509Certificate cer = System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(pfxPath);
                    if (String.IsNullOrEmpty(pfxPassword)) //是否证书加载是否需要密码
                        cer = new X509Certificate(pfxPath);
                    else
                        cer = new X509Certificate(pfxPath, pfxPassword);
                    webReq.ClientCertificates.Add(cer);

                }
                webReq.GetRequestStream().Write(buffer, 0, buffer.Length);
                webReq.GetRequestStream().Close();
                HttpWebResponse response = webReq.GetResponse() as HttpWebResponse;

                if (response.StatusCode == HttpStatusCode.OK)
                {

                }

               else

               {}

}

 

public static bool RemoteCertificateValidationCallback(Object sender,
           X509Certificate certificate,
           X509Chain chain,
           SslPolicyErrors sslPolicyErrors)
        {
            //如果没有错就表示验证成功
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            else
            {
                if((SslPolicyErrors.RemoteCertificateNameMismatch & sslPolicyErrors)==SslPolicyErrors.RemoteCertificateNameMismatch)
                {
                    tracing.WarnFmt("证书名称不匹配{0}", sslPolicyErrors);
                }
                
                 if((SslPolicyErrors.RemoteCertificateChainErrors & sslPolicyErrors)==SslPolicyErrors.RemoteCertificateChainErrors)
                {
                    string msg = "";
                    foreach (X509ChainStatus status in chain.ChainStatus)
                    {
                        msg+="status code ={0} "+status.Status;
                        msg += "Status info = "+status.StatusInformation+" ";
                    }
                     tracing.WarnFmt("证书链错误{0}", msg);
                }
                tracing.WarnFmt("证书验证失败{0}", sslPolicyErrors);
            }
            return false;
        }

 

private static string GetStream(System.IO.Stream stream, int contentlen)
        {
            byte[] buffer = new byte[contentlen];
            int len = 1024;
            int index = 0;
            while ((len = stream.Read(buffer, index, len)) > 0)
            {
                index = index + len;
            }

            return System.Text.Encoding.UTF8.GetString(buffer, 0, index);
        }

}

2 错误原因查看:

可以添加客户端端回调验证查看具体错误原因,错误原因在sslPolicyErrors 中显示

具体为SslPolicyErrors.RemoteCertificateNameMismatch一般是访问的url名字和证书中的cnname名称不一致

临时解决办法可以在本地host文件中加入

证书域名    访问IP地址

SslPolicyErrors.RemoteCertificateChainErrors 可以在chain.ChainStatus查看具体原因

 

3 常见问题解释:

3.1 SslPolicyErrors.RemoteCertificateNameMismatch一般是访问的url名字和证书中的cnname名称不一致

临时解决办法可以在本地host文件中加入

证书域名    访问IP地址

3.2   X509ChainStatusFlags.UntrustedRoot

     已处理证书链,但是在不受信任提供程序信任的根证书中终止

具体原因为客户端导入的证书不在本地信任列表中。

缺省导入是在本地用户中。

具体导入方法:

运行 -》 certmgr.msc

受信任人---右键----导入证书

另外服务或者web程序,其启动账号最好是安装证书的用户。如果用户没权限也会出现此问题

 

自己验证用户证书的方法:

using System;

using System.Configuration;

using System.IdentityModel.Selectors;

using System.IdentityModel.Tokens;

using System.Security.Cryptography.X509Certificates;
namespace ClientWeb.CustomX509Validator

{

/// <summary>

/// Implements the validator for X509 certificates.

/// </summary>

public class MyX509Validator: X509CertificateValidator

{

       /// <summary>

       /// Validates a certificate.

       /// </summary>

       /// <param name="certificate">The certificate the validate.</param>

       public override void Validate(X509Certificate2 certificate)

       {

         // validate argument

         if (certificate == null)

            throw new ArgumentNullException("X509认证证书为空!");

         // check if the name of the certifcate matches

         if (certificate.SubjectName.Name != ConfigurationManager.AppSettings["CertName"])

            throw new SecurityTokenValidationException("Certificated was not issued by thrusted issuer");

       }

}

}

<behaviors>

         <endpointBehaviors>

            <behavior name="myClientBehavior">

                   <clientCredentials>

                     <serviceCertificate>

                        <authentication certificateValidationMode="Custom" customCertificateValidatorType="ClientWeb.CustomX509Validator.MyX509Validator,ClientWeb" />

                     </serviceCertificate>

                   </clientCredentials>

            </behavior>

         </endpointBehaviors>

       </behaviors>

-----------------------------------------------------------------------------

正常情况下,处理https和http没有什么区别,如以下代码,显示了https://www.softlayer.com/的内容

string url = “https://www.softlayer.com/”;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1) {
     encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
Console.Write(reader.ReadToEnd());
response.Close();

和http的不同就是地址由http改为了https

但是,如果你将 https://www.softlayer.com/ 改为 https://softlayer.com/,会发现一个异常
未能为 SSL/TLS 安全通道建立信任关系
怎么回事? 用浏览器试一下,访问 https://www.softlayer.com/ 没有问题
访问 https://softlayer.com/ 会有证书问题(虽然是我们自己造成的)
这就对了,如果有证书问题,不做特殊处理,将会抛出异常
怎么处理呢? 如果是dot net 2.0 或以上,加上一个确认函数就可以了,代码如:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
string url = “https://softlayer.com/”;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1) {
     encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
Console.Write(reader.ReadToEnd());
response.Close();

public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { // Always accept
     Console.WriteLine(“accept ” + certificate.GetName());
     return true; //总是接受
}

using System.Net;
using System.IO;
using System.Web;
using System.Net.Security;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

如果是dot net 1.1,写法略有不同

ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();

internal class AcceptAllCertificatePolicy : ICertificatePolicy {
     public AcceptAllCertificatePolicy() {
     }
     public bool CheckValidationResult(ServicePoint sPoint, System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest wRequest, int certProb) {
     // Always accept
     return true;
     }
}


----------------------------------------------------------------------------------------------------------

我们使用https是,一般都只是服务器提供证书,用于验证服务器的身份
其实ssl是双向的,https有时也需要客户端提供证书,不少对安全性要求高的场合如银行业务就需要。
代码片段示例:

HttpWebRequest request;
//blabla
X509Certificate cer = X509Certificate.CreateFromCertFile(“你的cer证书文件”);
request.ClientCertificates.Add(cer);
//blabla

 

 

posted on 2011-03-21 16:37  ATAK  阅读(2556)  评论(1编辑  收藏  举报

导航