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

 

上一篇:PHP 审计


下一篇:[uwp开发]数据绑定那些事(1)