zoukankan      html  css  js  c++  java
  • 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);
            }
  • 相关阅读:
    Linux搭建www,mail,ftp三大DNS服务器
    linux基本命令
    Vmware网络不可达
    CentOS7基本配置一
    https
    阶段02JavaWeb基础day04mysql
    阶段02JavaWeb基础day02&03JavaScript
    阶段02JavaWeb基础day01html&css
    io复用select方法编写的服务器
    for循环 底层工作原理
  • 原文地址:https://www.cnblogs.com/wufanJY/p/10630408.html
Copyright © 2011-2022 走看看