【絕跡篇】RSA加密算法(私鑰加簽公鑰驗簽)


對於上上篇博客中我講的一個故事,本文引用: https://www.cnblogs.com/ButterflyEffect/p/9851403.html

故事中提到的關於加密會出現,私鑰加密,公鑰解密的情況,這種情況我們將它稱為【私鑰加簽,公鑰驗簽】
說句好理解的話:
既然是加密,那肯定是不希望別人知道我的消息,所以只有我才能解密,所以可得出【公鑰負責加密,私鑰負責解密】
同理,既然是簽名,那肯定是不希望有人冒充我發消息,只有我才能發布這個簽名,所以可得出【私鑰負責加簽,公鑰負責驗簽】

由以上得出關於安全性的問題,再舉個好例子:
現在有A(私鑰A、公鑰A),B(私鑰B、公鑰B) ,A向B發送消息,用私鑰A加簽、用公鑰B加密,發送給B,B用私鑰B解密,然后用公鑰A驗簽。
這樣的話就能保證是A發的消息,並且只有B自己才能解密。這樣是非常安全的!!!

話不多少,下面直接擼代碼,以下代碼是實現【私鑰加簽公鑰驗簽】的功能,公鑰加密私鑰解密的功能在我其它博客有講過...

 #region 私鑰加密,公鑰解密
        /// <summary>
        /// 私鑰加密
        /// </summary>
        /// <param name="privateKey">RSA私鑰 base64格式</param>
        /// <param name="contentData">待加密的數據</param>
        /// <param name="algorithm">加密算法</param>
        /// <returns></returns>
        public static string EncryptWithPrivateKey(string privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
        {
            return Convert.ToBase64String(EncryptWithPrivateKey(Convert.FromBase64String(privateKey), contentData, algorithm));
        }
        /// <summary>
        /// 私鑰加密
        /// </summary>
        /// <param name="privateKey">RSA私鑰</param>
        /// <param name="contentData">待加密的數據</param>
        /// <param name="algorithm">加密算法</param>
        /// <returns></returns>
        public static byte[] EncryptWithPrivateKey(byte[] privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKey);
            return Transform(privateKeyParam, contentData, algorithm, true);
        }
        /// <summary>
        /// 公鑰解密
        /// </summary>
        /// <param name="publicKey">RSA公鑰  base64格式</param>
        /// <param name="content">待解密數據 base64格式</param>
        /// <param name="encoding">解密出來的數據編碼格式,默認UTF-8</param>
        /// <param name="algorithm">加密算法</param>
        /// <returns></returns>
        public static string DecryptWithPublicKey(string publicKey, string content, string encoding = "UTF-8", string algorithm = "RSA/ECB/PKCS1Padding")
        {
            return Encoding.GetEncoding("GB2312").GetString(DecryptWithPublicKey(Convert.FromBase64String(publicKey), Convert.FromBase64String(content), algorithm));
        }
        /// <summary>
        /// 公鑰解密
        /// </summary>
        /// <param name="publicKey">RSA公鑰</param>
        /// <param name="contentData">待解密數據</param>
        /// <param name="algorithm">加密算法</param>
        /// <returns></returns>
        public static byte[] DecryptWithPublicKey(byte[] publicKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
        {
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKey);
            return Transform(publicKeyParam, contentData, algorithm, false);
        }
 #endregion
        private static byte[] Transform(AsymmetricKeyParameter key, byte[] contentData, string algorithm, bool forEncryption)
        {
            var c = CipherUtilities.GetCipher(algorithm);
            c.Init(forEncryption, new ParametersWithRandom(key));
            return c.DoFinal(contentData);
        }

順帶提下,這里的第三方RSA引用包可以在【程序包管理器控制台】輸入命令提示
PM> Install-Package BouncyCastle
完成包的安裝

static void Main(string[] args)
{
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            string xmlPrivateKey = rsa.ToXmlString(true);//XML密鑰
            string xmlPublicKey = rsa.ToXmlString(false);//XML公鑰

            string str = "測試數據";
            byte[] b = System.Text.Encoding.Default.GetBytes(str);//字符串轉字節數組,byte[]

            string EncryptedData = EncryptWithPrivateKey(B(xmlPrivateKey), b);//返回加密后的base64格式數據
            Console.WriteLine("私鑰加密結果:" + EncryptedData);
            string DecipheringData = DecryptWithPublicKey(A(xmlPublicKey), EncryptedData);//返回解密后的明文數據
            Console.WriteLine("公鑰解密結果:" + DecipheringData);

            Console.ReadLine();
}

//XML格式轉base64格式,公鑰
public static string A(string xml)
{
            var rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xml);
            var p = rsa.ExportParameters(false);
            RsaKeyParameters key = new RsaKeyParameters(false, new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent));

            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key);
            byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
            string publicKey = Convert.ToBase64String(serializedPublicBytes);
            return publicKey;
}

//XML格式轉base64格式,私鑰
public static string B(string xml)
{
            var rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xml);
            var p = rsa.ExportParameters(true);
            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key);
            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
            string privateKey = Convert.ToBase64String(serializedPrivateBytes);
            return privateKey;
}

最后加密測試可以在這個網站去測試 http://tool.chacuo.net/cryptrsapubkey


免責聲明!

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



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