RSA 加密/解密—PKCS8 (Java與C#互通BouncyCastle)

前提:

需要調用JavaAPI進行簽名/驗籤、加密/解密,需要使用BouncyCastle 類庫進行Java與C#之間的數據互通。

 

加密理解點:

1:java 私鑰採用的是PKCS8 ;C# 私鑰採用的是PKCS1 格式

2:RSA加密 公鑰加密,私鑰解密或者私鑰加密和公鑰解密【這點和簽名sign不同,sign需要私鑰簽名】

3:如果 java RSA加密 最後生成16進制 C#  也需要統一。這點一般需要確認最後生成的爲base64還是16進制數據。

 

額外補充:

1:私鑰,公鑰注意去除空格,換行等(.Replace("\r", "").Replace("\n", "").Replace("\\s", ""))

2:加密 最後生成的一般爲 byte數組 ,但是由於java中byte的範圍在 [-128,127] 但是 C#中byte的範圍在 [0,255]

並且使用byte不好進行對比傳輸,所以我們在進行簽名或者加密時一般轉化爲字符串或者16進制。

 

BouncyCastle類庫下載:

https://download.csdn.net/download/u011791378/11236710

 

******************以下時加密解密(C#與Java互通)BouncyCastle *************************

        /// <summary>
        /// 私鑰加密2
        /// </summary>
        /// <param name="content">加密內容</param>
        /// <param name="PrivateKey">PKCS8私鑰</param>
        /// <returns></returns>
        public string EncryptByPrivateKey2(string content, string PrivateKey)
        {
            RsaKeyParameters PrivateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(PrivateKey));
            var original = new BigInteger(Encoding.UTF8.GetBytes(content));

            //加密
            var encrypted = original.ModPow(PrivateKeyParam.Exponent, PrivateKeyParam.Modulus);
            //16進制
            return PayUtils.byteArray2HexString(encrypted.ToByteArray());
            //base64
            //return Convert.ToBase64String(encrypted.ToByteArray());
        }
        /// <summary>
        /// 公鑰解密2
        /// </summary>
        /// <param name="content">解密內容</param>
        /// <param name="PublicKey">PKCS8公鑰</param>
        /// <returns></returns>
        public string DecryptByPublicKey2(string content, string PublicKey)
        {
            //base64
            //byte[] byteData = Convert.FromBase64String(content);
            //16進制
            var data = PayUtils.hexString2ByteArray(content);
            RsaKeyParameters PublicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(PublicKey));
            var encrypted = new BigInteger(data);

            //解密
            var decrypted = encrypted.ModPow(PublicKeyParam.Exponent, PublicKeyParam.Modulus);
            return Encoding.UTF8.GetString(decrypted.ToByteArray());

        }

        /// <summary>
        /// RSA公鑰加密
        /// </summary>
        /// <param name="content">加密內容</param>
        /// <param name="publickey">公鑰</param>
        /// <returns></returns>
        public string EncryptByPublicKey(string content, string publicKey)
        {
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
            var original = new BigInteger(Encoding.UTF8.GetBytes(content));


            //加密
            var encrypted = original.ModPow(publicKeyParam.Exponent, publicKeyParam.Modulus);
            //16進制
            return PayUtils.byteArray2HexString(encrypted.ToByteArray());
            //base64
            //return Convert.ToBase64String(encrypted.ToByteArray());
        }
        /// <summary>
        /// RSA私鑰解密
        /// </summary>
        /// <param name="content">解密內容</param>
        /// <param name="privateKey">私鑰</param>
        /// <returns></returns>
        public string DecryptByPrivateKey(string content, string privateKey)
        {
            //base64
            //byte[] byteData = Convert.FromBase64String(content);
            //16進制
            var data = PayUtils.hexString2ByteArray(content);
            RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
            var encrypted = new BigInteger(data);

            //解密
            var decrypted = encrypted.ModPow(privateKeyParam.Exponent, privateKeyParam.Modulus);
            return Encoding.UTF8.GetString(decrypted.ToByteArray());

        }

*****************Bytes數組與16進制的轉換*************************

        private static readonly string hexChars = "0123456789ABCDEF";
        /// <summary>
        /// Bytes數組轉爲16進制
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string byteArray2HexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                byte lo = (byte)(0xF & data[i]);
                byte hi = (byte)((int)((uint)(0xF0 & data[i]) >> 4));
                sb.Append(hexChars.Substring(hi, 1)).Append(hexChars.Substring(lo, 1));
            }
            return sb.ToString();
        }
        /// <summary>
        /// 16進制轉爲Bytes數組
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public static byte[] hexString2ByteArray(String hexStr)
        {
            if (hexStr.Length % 2 != 0)
            {
                return null;
            }
            byte[] data = new byte[hexStr.Length / 2];
            for (int i = 0; i < hexStr.Length / 2; i++)
            {
                char hc = hexStr.Substring(2 * i, 1).ToCharArray()[0];//.charAt(2 * i);
                char lc = hexStr.Substring(2 * i + 1, 1).ToCharArray()[0];//.charAt(2 * i + 1);
                byte hb = hexChar2Byte(hc);
                byte lb = hexChar2Byte(lc);
                if ((hb < 0) || (lb < 0))
                {
                    return null;
                }
                int n = hb << 4;
                data[i] = ((byte)(n + lb));
            }
            return data;
        }
        private static byte hexChar2Byte(char c)
        {
            if ((c >= '0') && (c <= '9'))
            {
                return (byte)(c - '0');
            }
            if ((c >= 'a') && (c <= 'f'))
            {
                return (byte)(c - 'a' + 10);
            }
            if ((c >= 'A') && (c <= 'F'))
            {
                return (byte)(c - 'A' + 10);
            }
            return 0;
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章