C#解决“因为算法不同,客户端和服务器无法通信”的问题
作者:初九之潜龙勿用
实现微信退款功能,我们需要在微信支付商户后台申请安全证书,并调用退款API URL,在调试过程中为增添返回调试信息属性,调试一切正常,但再次覆盖的时候,调用显示为 “ 因为算法不同,客户端和服务器无法通信,” ,本文介绍了C#解决因为算法不同,客户端和服务器无法通信的问题
故障现象
实现微信退款功能,我们需要在微信支付商户后台申请安全证书,并调用退款API URL。在调试过程中为增添返回调试信息属性,重新对.net FrameWorkd 类库进行编译并部署,调试一切正常,但再次覆盖的时候,调用显示为 “ 因为算法不同,客户端和服务器无法通信。” ,系统返回错误:
类似调用如下代码:
string cert = @"D:\wxpay\apiclient_cert.p12"; string password = "14302"; string post_data = getRefundOrderXml(refundorder, key); string request_data = PostXmlAndCertToUrl(RefundOrderUrl, post_data,cert,password);
问题出在 PostXmlAndCertToUrl 调用上,cert 为申请证书的存放位置,passwrd 为证书密码。
开发运行环境
操作系统: Windows Server 2019 DataCenter
.net版本: .netFramework4.7.2
开发工具:VS2019 C#
解决
System.Net.ServicePointManager.SecurityProtocol 属性可选择安全套接字层 (SSL) 或传输层安全 (TLS) 协议的版本,可能是由于协议版本不匹配造成的此原因,通过在Page_Load 服务器事件添加如下语句,问题解决:
void Page_Load(Object sender, EventArgs e) { System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; }
实现携带证书的 API URL调用
PostXmlAndCertToUrl 实现了携带安全证书访问 API 的能力,说明见下表:
序号 | 参数名 | 类型 | 说明 |
---|---|---|---|
1 | url | string | 要访问的 API URL 地址 |
2 | post_data | string | 要 POST 的指定规则内容 |
3 | cert | string | API 安全证书存放存储的全路径地址 |
4 | password | string | 证书密码 |
实现代码如下:
public string PostXmlAndCertToUrl(string url, string postData,string cert,string password) { string resp = string.Empty; ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); System.Security.Cryptography.X509Certificates.X509Certificate2 cer = new System.Security.Cryptography.X509Certificates.X509Certificate2(cert, password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet); HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url); webrequest.ClientCertificates.Add(cer); webrequest.Method = "post"; webrequest.ContentType = "application/x-www-form-urlencoded"; webrequest.ContentLength = postData.Length; HttpWebResponse response = null; try { StreamWriter swRequestWriter = new StreamWriter(webrequest.GetRequestStream()); swRequestWriter.Write(postData); if (swRequestWriter != null) swRequestWriter.Close(); response = (HttpWebResponse)webrequest.GetResponse(); using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { resp = reader.ReadToEnd(); } } catch (Exception exp) { throw exp; } finally { if (response != null) response.Close(); } return resp; } private static bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors) { if (errors == System.Net.Security.SslPolicyErrors.None) return true; return false; }
到此这篇关于C#解决“因为算法不同,客户端和服务器无法通信”的问题的文章就介绍到这了,更多相关C#客户端和服务器无法通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!