zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    林大妈的JavaScript进阶知识(二):JS异步行为
    前端技术基础(一):浏览器相关
    林大妈的JavaScript进阶知识(一):对象与内存
    林大妈的JavaScript进阶知识(四):HTML5 History API
    林大妈的CSS知识清单(二)可见格式化模型(内含margin塌陷与浮动闭合的解决方案)
    林大妈的CSS知识清单(一)添加样式
    林大妈的JavaScript基础知识(三):JavaScript编程(4)数组
    林大妈的JavaScript基础知识(三):JavaScript编程(3)原型
    林大妈的JavaScript基础知识(三):JavaScript编程(2)函数
    基于vue-cli快速构建
  • 原文地址:https://www.cnblogs.com/bayonetxxx/p/1990493.html
Copyright © 2011-2022 走看看