在与建设银行做对接的项目的时候,签名的时候需要用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。。