1 基本编程方法: 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> |