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


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

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

 

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

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();
        }

 

 一、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()));
        }

二、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();
        }

三、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);
        }

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

        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;
        }

 

五、解密返回數據

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);
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM