在與建設銀行做對接的項目的時候,簽名的時候需要用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。。