.Net版本SHA256WithRSA算法-程序员宅基地

技术标签: c#  git  json  

在与建设银行做对接的项目的时候,签名的时候需要用SHA256WithRSA算法,因为只有java版本的代码,所以需要自己改写一版.Net算法代码。

1、证书的生成(OpenSSL)

由于我们对接需要互相认证对方的证书,这里的证书要求是SSL证书,网上有很多安装教程可以参考,这里给大家介绍一种比较好的OpenSSL插件,在我们经常使用的项目管理器Git,在安装的时候已经自带了一个OpenSSL插件,我们可以直接运行这个文件,路径是:“C:\Program Files\Git\mingw64\bin\openssl.exe”,如下图(注:需要使用管理员身份运行)

命令行如下

1 openssl genrsa -des3 -out test.key 2048 //需要输入私钥密码   
2 openssl req -new -key test.key -out test.csr
3 openssl x509 -req -in test.csr -out test.cer -signkey test.key -days 7500  //有效时间
4 openssl pkcs12 -export -clcerts -in test.cer -inkey test.key -out test.pfx
5 
6 //test.cer为公钥证书,test.pfx为私钥证书

证书如下(test.cer为公钥证书,test.pfx为私钥证书)

2、算法代码

生成好证书就可以写算法代码了,直接上代码。

项目引用: using System.Security.Cryptography;using System.Security.Cryptography.X509Certificates;

 1  /// <summary>
 2         /// 签名算法--SHA256WithRSA
 3         /// </summary>
 4         /// <param name="dataStr">配置json</param>
 5         /// <param name="keyFile">证书路径</param>
 6         /// <param name="password">证书密码</param>
 7         /// <returns></returns>
 8         public static string Sha256Sign(string dataStr, string keyFile, string password)
 9         {
10             using (RSACryptoServiceProvider sha256 = new RSACryptoServiceProvider())
11             {
12                 var privateKey = GetPrivateKey(keyFile, password);  //获取私钥
13                 byte[] dataInBytes = DafaultEncoding.GetBytes(dataStr);
14                 sha256.FromXmlString(privateKey);
15                 byte[] inArray = sha256.SignData(dataInBytes, CryptoConfig.MapNameToOID("SHA256"));
16                 string sign = Convert.ToBase64String(inArray);
17                 return sign;
18             }
19         }
 1  /// <summary>
 2         /// 获取私钥
 3         /// </summary>
 4         /// <param name="path">文件路径</param>
 5         /// <param name="password">文件秘钥</param>
 6         /// <returns></returns>
 7         public static string GetPrivateKey(string path, string password)
 8         {
 9             try
10             {
11                 X509Certificate2 cert = new X509Certificate2(path, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
12                 return cert.PrivateKey.ToXmlString(true);
13             }
14             catch
15             {
16                 return "";
17             }
18         }

3、发签名和数据

 1  public static string SendPostRequestJson(string url, string appId, string jsonData,string version, string tenancyId,string passWord, Encoding encoding)
 2         {
 3             if (string.IsNullOrEmpty(url))
 4                 throw new ArgumentNullException("url");
 5 
 6             if (encoding == null)
 7                 encoding = Encoding.UTF8;
 8 
 9             //var dataString = string.Join("&", data.Select(pattern => pattern.Key + "=" + pattern.Value));
10 
11             var sign = SignHelper.Sha256Sign(jsonData, "E:/1-trunk/CCB.JobService/CcbApi/files/test.pfx", passWord);
12 
13             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
14             request.Method = "POST";
15             request.ContentType = "application/json; charset=" + encoding.WebName;
16             request.Timeout = 60000;
17             request.UserAgent = "IIS";
18             request.Headers.Add("C-Signature", sign);
19             request.Headers.Add("C-App-Id", appId);
20             request.Headers.Add("C-Business-Id", SignHelper.GetBussinessId(appId));
21             request.Headers.Add("C-Timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
22             request.Headers.Add("version", version);
23             request.Headers.Add("C-Tenancy-Id", tenancyId);
24             if (jsonData != null)
25             {
26                 byte[] buffer = encoding.GetBytes(jsonData);
27                 string json = Convert.ToBase64String(buffer);
28 
29                 byte[] buffer1 = encoding.GetBytes(json);
30 
31                 using (Stream stream = request.GetRequestStream())
32                 {
33                     stream.Write(buffer1, 0, buffer1.Length);
34                 }
35             }
36 
37             using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
38             {
39                 return ReadResponse(response);
40             }
41         }
42 
43         /// <summary>
44         /// 读取响应内容。
45         /// </summary>
46         /// <param name="response"></param>
47         /// <returns></returns>
48         private static string ReadResponse(HttpWebResponse response)
49         {
50             if (response == null) return string.Empty;
51             Stream strem = null;
52             if (response.Headers["Content-Encoding"] == "gzip")
53                 strem = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress);
54             else
55                 strem = response.GetResponseStream();
56 
57             if (strem == null) return string.Empty;
58             using (StreamReader reader = new StreamReader(strem))
59             {
60                 return reader.ReadToEnd();
61             }
62         }

4、通用接口

 1 /// <summary>
 2         /// 通用接口
 3         /// </summary>
 4         /// <typeparam name="T">返回数据实体</typeparam>
 5         /// <param name="jsonDate">要传输的参数json字符串</param>
 6         /// <param name="url">接口URL</param>
 7         /// <returns>响应数据</returns>
 8         private static ResponseBase<T> InvokApi<T>(string jsonDate, string url)
 9         {
10             try
11             {
12                 url = CcbUrl + url;
13                 var result = HttpWebRequestHelper.SendPostRequestJson(url, AppId, jsonDate, Version, TenancyId, PassWord, Encoding.UTF8);
14                 if (!string.IsNullOrEmpty(result))
15                 {
16                     result = DecodeBase64(Encoding.UTF8, result);
17                 }
18                 var res = JsonConvert.DeserializeObject<ResponseBase<T>>(result);
19                 if (res.Status != "00")
20                 {
21                     LogHelper.Log(DateTime.Now + url + ":调用建设银行接口:" + jsonDate);
22                     LogHelper.Log(DateTime.Now + ": 调用建设银行返回:" + JsonConvert.SerializeObject(result));
23                 }
24 
25                 return res;
26             }
27             catch (Exception e)
28             {
29                 return new ResponseBase<T>();
30             }
31 
32         }

over。。

 

转载于:https://www.cnblogs.com/MirZhai/p/10886665.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30512785/article/details/96406912

智能推荐

python编码问题之encode、decode、codecs模块_python中encode在什么模块-程序员宅基地

文章浏览阅读2.1k次。原文链接先说说编解码问题编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。 Eg:str1.decode('gb2312') #将gb2312编码的字符串转换成unicode编码str2.encode('gb2312') #将unicode编码..._python中encode在什么模块

Java数据流-程序员宅基地

文章浏览阅读949次,点赞21次,收藏15次。本文介绍了Java中的数据输入流(DataInputStream)和数据输出流(DataOutputStream)的使用方法。

ie浏览器无法兼容的问题汇总_ie 浏览器 newdate-程序员宅基地

文章浏览阅读111次。ie无法兼容_ie 浏览器 newdate

想用K8s,还得先会Docker吗?其实完全没必要-程序员宅基地

文章浏览阅读239次。这篇文章把 Docker 和 K8s 的关系给大家做了一个解答,希望还在迟疑自己现有的知识储备能不能直接学 K8s 的,赶紧行动起来,K8s 是典型的入门有点难,后面越用越香。

ADI中文手册获取方法_adi 如何查看数据手册-程序员宅基地

文章浏览阅读561次。ADI中文手册获取方法_adi 如何查看数据手册

React 分页-程序员宅基地

文章浏览阅读1k次,点赞4次,收藏3次。React 获取接口数据实现分页效果以拼多多接口为例实现思路加载前 加载动画加载后 判断有内容的时候 无内容的时候用到的知识点1、动画效果(用在加载前,加载之后就隐藏或关闭,用开关效果即可)2、axios请求3、map渲染页面4、分页插件(antd)代码实现import React, { Component } from 'react';//引入axiosimport axios from 'axios';//引入antd插件import { Pagination }_react 分页

随便推点

关于使用CryPtopp库进行RSA签名与验签的一些说明_cryptopp 签名-程序员宅基地

文章浏览阅读449次,点赞9次,收藏7次。这个变量与验签过程中的SignatureVerificationFilter::PUT_MESSAGE这个宏是对应的,SignatureVerificationFilter::PUT_MESSAGE,如果在签名过程中putMessage设置为true,则在验签过程中需要添加SignatureVerificationFilter::PUT_MESSAGE。项目中使用到了CryPtopp库进行RSA签名与验签,但是在使用过程中反复提示无效的数字签名。否则就会出现文章开头出现的数字签名无效。_cryptopp 签名

新闻稿的写作格式_新闻稿时间应该放在什么位置-程序员宅基地

文章浏览阅读848次。新闻稿是新闻从业者经常使用的一种文体,它的格式与内容都有着一定的规范。本文将从新闻稿的格式和范文两个方面进行介绍,以帮助读者更好地了解新闻稿的写作_新闻稿时间应该放在什么位置

Java中的转换器设计模式_java转换器模式-程序员宅基地

文章浏览阅读1.7k次。Java中的转换器设计模式 在这篇文章中,我们将讨论 Java / J2EE项目中最常用的 Converter Design Pattern。由于Java8 功能不仅提供了相应类型之间的通用双向转换方式,而且还提供了转换相同类型对象集合的常用方法,从而将样板代码减少到绝对最小值。我们使用Java8 功能编写了..._java转换器模式

应用k8s入门-程序员宅基地

文章浏览阅读150次。1,kubectl run创建pods[root@master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1[root@master ~]# kubectl get podsNAME READY STATUS REST...

PAT菜鸡进化史_乙级_1003_1003 pat乙级 最优-程序员宅基地

文章浏览阅读128次。PAT菜鸡进化史_乙级_1003“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。得到“答案正确”的条件是: 1. 字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符; 2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或..._1003 pat乙级 最优

CH340与Android串口通信_340串口小板 安卓给安卓发指令-程序员宅基地

文章浏览阅读5.6k次。CH340与Android串口通信为何要将CH340的ATD+Eclipse上的安卓工程移植到AndroidStudio移植的具体步骤CH340串口通信驱动函数通信过程中重难点还存在的问题为何要将CH340的ATD+Eclipse上的安卓工程移植到AndroidStudio为了在这个工程基础上进行改动,验证串口的数据和配置串口的参数,我首先在Eclipse上配置了安卓开发环境,注意在配置环境是..._340串口小板 安卓给安卓发指令