首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C# 解决“因为算法不同,客户端和服务器无法通信”的问题

C# 解决“因为算法不同,客户端和服务器无法通信”的问题

作者头像
初九之潜龙勿用
发布2024-12-28 10:28:25
发布2024-12-28 10:28:25
30200
代码可运行
举报
文章被收录于专栏:技术文章技术文章
运行总次数:0
代码可运行

故障现象

实现微信退款功能,我们需要在微信支付商户后台申请安全证书,并调用退款API URL。在调试过程中为增添返回调试信息属性,重新对.net FrameWorkd 类库进行编译并部署,调试一切正常,但再次覆盖的时候,调用显示为 “ 因为算法不同,客户端和服务器无法通信。” ,系统返回错误:

类似调用如下代码:

代码语言:javascript
代码运行次数:0
运行
复制
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 服务器事件添加如下语句,问题解决:

代码语言:javascript
代码运行次数:0
运行
复制
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

证书密码

实现代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 故障现象
  • 开发运行环境
  • 解决
    • 实现携带证书的 API URL调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档