c#RSA的SHA1加密與AES加密、解密

    前言:公司項目對接了一個對數據保密性要求較高的java公司。api接口邏輯是這樣的:他們提供 SHA1私鑰 與 AES的祕鑰。咱們須要將 傳遞查詢參數 經過SHA1 私鑰加密再轉換成 十六進制 字符串。傳遞查詢參數 再經過 AES祕鑰 加密轉換成十六進制 字符串。java

查詢結果 也是一個十六進制字符串 須要轉換成 byte 數組 再經過AES祕鑰解密成 返回數據。web

 

後面轉換接口都須要十六進制字符串與byte數組 相互轉換。這個具體得看開發者本身的接口要求了。我這邊的項目要求 就是數據傳遞用十六進制字符串比較多。json

1.十六進制字符串轉換成byte數組

/// <summary>
        /// 十六進制字符串換成byte數組轉 /// </summary>
        /// <param name="byteArray"></param>
        /// <returns></returns>
        private static byte[] HexStringToByteArray(string s) { s = s.Replace(" ", ""); byte[] buffer = new byte[s.Length / 2]; for (int i = 0; i < s.Length; i += 2) { buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16); } return buffer; }

2.byte數組轉換成十六進制字符串

/// <summary>
        /// byte數組轉換成十六進制字符串 /// </summary>
        /// <param name="byteArray"></param>
        /// <returns></returns>
        private string bytesToHexStr(byte[] byteArray) { StringBuilder sb = new StringBuilder(); foreach (byte b in byteArray) { sb.Append(b.ToString("X2")); } return sb.ToString(); }

 

 1、privateKey私鑰轉換成xml

.net的RSA僅僅支持 xml格式。第一步須要將java那邊提供的SHA1私鑰轉換成xml格式

/// <summary>
        /// 私鑰=>十六進制字符串轉換成xml /// </summary>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        private static string RSAPrivateKeyJava2DotNet(string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(HexStringToByteArray(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); }

2、c#SHA1加密

數據轉換過程當中 套有一個md5加密MD5Encrypt(都是按照乙方java的加密規則寫的 我也以爲很繁瑣)

/// <summary>
        /// ASYMMETRY_ALGORITHM 加密類 SHA1 /// </summary>
        /// <param name="signaturePrivateKey"></param>
        /// <param name="signatureData">請求參數</param>
        /// <returns></returns>
        private string signature(string signaturePrivateKey, string signatureData) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); var privateJavaKey = signaturePrivateKey; var privateCSharpKey = RSAPrivateKeyJava2DotNet(privateJavaKey); rsa.FromXmlString(privateCSharpKey); var md5 = MD5Encrypt(signatureData); byte[] signatureBytes = rsa.SignData(Encoding.UTF8.GetBytes(md5), "SHA1"); var hexStr = bytesToHexStr(signatureBytes); return hexStr; }

MD5Encrypt

/// <summary>
        /// 用MD5加密字符串 /// </summary>
        /// <param name="jsonData">待加密的字符串</param>
        /// <returns></returns>
        public string MD5Encrypt(string jsonData) { MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider(); byte[] hashedDataBytes; hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(jsonData)); StringBuilder tmp = new StringBuilder(); foreach (byte i in hashedDataBytes) { tmp.Append(i.ToString("x2")); } return tmp.ToString(); }

3、AES加密

/// <summary>
        /// AES解密 /// </summary>
        /// <param name="signaturePrivateKey"></param>
        /// <param name="signatureData"></param>
        /// <returns></returns>
        private string decrypt(string key, string str) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = HexStringToByteArray(str); RijndaelManaged rm = new RijndaelManaged { Key = HexStringToByteArray(key), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = rm.CreateDecryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); }

4、請求接口獲取返回數據

public objcet callIntegrateService() { var date = DateTime.Now; var startTime = Convert.ToDateTime(date.ToString("yyyy-MM-dd") + " 00:00:00"); var endTime = date; var logstart = ConvertDateTimeInt(startTime);//datetime轉換成時間戳Unix var logend = ConvertDateTimeInt(endTime); //var jsonData = "{}";
                var jsonData ="{ startTime: \"" + logstart + "\",endTime:\"" + logend + "\" }"; var url = base_url + "/getProjectAttendanceDetail"; string signature = getSignatrue(jsonData); string encryptData = encrypt(secretKey, jsonData); var param = "{ clientSerial:\""+ clientSerial + "\",projectId:\"" + projectId + "\",jsonData:\"" + encryptData + "\",signature:\"" + signature + "\" }"; var result= webPost(url, param); var objresult = JsonConvert.DeserializeObject<request>(result); var response = objresult.response; var data = decrypt(secretKey, response); var objdata = JsonConvert.DeserializeObject(data); return objdata; }

 

5、解密返回數據

AES解密

/// <summary>
        /// AES解密 /// </summary>
        /// <param name="signaturePrivateKey"></param>
        /// <param name="signatureData"></param>
        /// <returns></returns>
        private string decrypt(string key, string str) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = HexStringToByteArray(str); RijndaelManaged rm = new RijndaelManaged { Key = HexStringToByteArray(key), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = rm.CreateDecryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); }
相關文章
相關標籤/搜索