加解密算法二:非对称加解密及RSA算法的实现

时间:2021-06-22 23:21:02
  加密和解密使用不同的密钥的一类加密算法。这类加密算法通常有两个密钥A和B,使用密钥A加密数据得到的密文,只有密钥B可以进行解密操作(即使密钥A也无法解密);
相反,使用密钥B加密数据得到的密文,只有密钥A可以解密。这两个密钥分别称为私钥和公钥。私钥就是你个人保留,不能公开的密钥,而公钥则是公开给加解密操作的另一方的。
根据不同用途,对数据进行加密所使用的密钥也不相同(有时用公钥加密,私钥解密;有时相反用私钥加密,公钥解密)。非对称加密的代表算法是RSA算法。
  

    RSA算法是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。它的安全性是基于大整数素因子分解的困难性,而大整数因子分解问题是数学上的著名难题,至今没有有效的方法予以解决,因此可以确保RSA算法的安全性。

  

公钥和私钥的产生:

        public static void CreatePublicAndPrivateKey(out string publicKey, out string privateKey)
        {
            //声明一个RSA算法的实例,由RSACryptoServiceProvider类型的构造函数指定了密钥长度为1024位
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);

            //实例化RSACryptoServiceProvider后,RSACryptoServiceProvider会自动生成密钥信息
            publicKey = rsaProvider.ToXmlString(false);
            privateKey = rsaProvider.ToXmlString(true);
        }

 

公钥加密,私钥解密:

        public static string RSAEncryptWithPublicKey(string source, string publicKey)
        {
            if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(publicKey)) { return ""; }
            else
            {
                try
                {
                    byte[] data = Encoding.Default.GetBytes(source);
                    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);

                    //将公钥导入到RSA对象中,准备加密
                    rsaProvider.FromXmlString(publicKey);

                    int keySize = rsaProvider.KeySize / 8;
                    int bufferSize = keySize - 11;
                    byte[] buffer = new byte[bufferSize];
                    MemoryStream msInput = new MemoryStream(data);
                    MemoryStream msOuput = new MemoryStream();
                    int readLen = msInput.Read(buffer, 0, bufferSize);
                    while (readLen > 0)
                    {
                        byte[] dataToEnc = new byte[readLen];
                        Array.Copy(buffer, 0, dataToEnc, 0, readLen);
                        byte[] encData = rsaProvider.Encrypt(dataToEnc, false);//加密
                        msOuput.Write(encData, 0, encData.Length);
                        readLen = msInput.Read(buffer, 0, bufferSize);
                    }

                    msInput.Close();
                    byte[] result = msOuput.ToArray();//得到加密结果
                    msOuput.Close();
                    rsaProvider.Clear();
                    return Convert.ToBase64String(result);
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
        }

        public static string RSADecryptWithPrivateKey(string source, string privateKey)
        {
            if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(privateKey)) { return ""; }
            else
            {
                try
                {
                    byte[] data = Convert.FromBase64String(source);
                    //byte[] data = Encoding.Default.GetBytes(source);
                    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);

                    //将私钥导入RSA中,准备解密
                    rsaProvider.FromXmlString(privateKey);

                    int keySize = rsaProvider.KeySize / 8;
                    byte[] buffer = new byte[keySize];
                    MemoryStream msInput = new MemoryStream(data);
                    MemoryStream msOuput = new MemoryStream();
                    int readLen = msInput.Read(buffer, 0, keySize);
                    while (readLen > 0)
                    {
                        byte[] dataToDec = new byte[readLen];
                        Array.Copy(buffer, 0, dataToDec, 0, readLen);
                        byte[] decData = rsaProvider.Decrypt(dataToDec, false);//解密
                        msOuput.Write(decData, 0, decData.Length);
                        readLen = msInput.Read(buffer, 0, keySize);
                    }
                    msInput.Close();
                    byte[] result = msOuput.ToArray();//得到解密结果
                    msOuput.Close();
                    rsaProvider.Clear();
                    return Encoding.Default.GetString(result);
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
        }