21
2020
12

DES、3DES、AES、RSA加密算法对比

DES-非机密数据加密标准,可用于兼容旧系统,新系统不建议使用

3DES-DES的加强版,DES到AES之间的过渡算法

AES-高级加密标准,替代DES

RSA-非对称加密解密算法,多用于签名验证,加密解决速度慢,不建议用于大量数据的加密解密

目前跨系统间的加密数据通讯,一般是RSA与AES两种加密算法结合使用,RSA用于对AES密钥进行加密解密,AES用于对交易数据进行加密解密


算法代码:

    public class EncryptHelper
    {
        //DES算法8位加密key,一般存在数据库或文件中
        private static string defaultDesKey = "j5ca9aEn";
        //DES算法8位加密向量,一般存在数据库或文件中
        private static string defaultDesIv = "GTRSQ96C";
        //3DES算法12位加密向量,一般存在数据库或文件中
        private static string defaultTripleDesIV = "68Hfwj3kfX=T";
        //3DES算法32位加密key,一般存在数据库或文件中
        private static string defaultTripleDesKey = "QdpQGoa+8SA9dxhVs6DSXLfUGqw+Ahtd";

        /// <summary>
        /// Aes加解密钥必须32位,一般存在数据库或文件中
        /// </summary>
        private static string defaultAesKey = "ZdpQGoa+0SA1dxhVs7DSXLfUGqw-Ahtg";

        #region DES加密解密-非机密数据的正式数据加密标准(DES Data Encryption Standard)
        //默认密钥向量
        //private static readonly byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

        #region DES加密

        /// <summary> 
        /// 加密数据 
        /// </summary> 
        /// <param name="input">需要加密的字符串</param> 
        /// <param name="sKey">加密秘钥,不传则默认为指定的值</param> 
        /// <param name="sIv">加密向量,不传则默认为指定的值</param> 
        /// <returns></returns> 
        public static string DESEncrypt(string input, string sKey = "", string sIv = "")
        {
            if (string.IsNullOrEmpty(input))
                return String.Empty;
            if (string.IsNullOrEmpty(sKey)) sKey = defaultDesKey;
            else if (sKey.Length > 8) sKey = sKey.Substring(0, 8);
            if (string.IsNullOrEmpty(sIv)) sIv = defaultDesIv;
            else if (sIv.Length > 8) sIv = sIv.Substring(0, 8);

            var des = new DESCryptoServiceProvider();
            MemoryStream ms = null;
            CryptoStream encStream = null;
            StreamWriter sw = null;
            string result;

            try
            {
                var key = Encoding.UTF8.GetBytes(sKey);
                var iv = Encoding.UTF8.GetBytes(sIv);
                ms = new MemoryStream();

                encStream = new CryptoStream(ms, des.CreateEncryptor(key, iv), CryptoStreamMode.Write);

                sw = new StreamWriter(encStream);

                sw.Write(input);

                sw.Flush();
                encStream.FlushFinalBlock();
                ms.Flush();


                result = Convert.ToBase64String(ms.GetBuffer(), 0, Convert.ToInt32(ms.Length, System.Globalization.CultureInfo.InvariantCulture));
            }
            finally
            {
                if (sw != null)
                    sw.Close();
                if (encStream != null)
                    encStream.Close();
                if (ms != null)
                    ms.Close();
            }

            return result;
        }

        #endregion

        #region DES解密
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="input">需要解密的字符串</param> 
        /// <param name="sKey">加密秘钥,不传则默认为指定的值</param> 
        /// <param name="sIv">加密向量,不传则默认为指定的值</param> 
        /// <returns></returns> 
        public static string DESDecrypt(string input, string sKey = "", string sIv = "")
        {
            byte[] buffer;
            try
            {
                buffer = Convert.FromBase64String(input);
            }
            catch (System.ArgumentNullException)
            {
                return String.Empty;
            }
            catch (System.FormatException)
            {
                return String.Empty;
            }

            var des = new DESCryptoServiceProvider();
            MemoryStream ms = null;
            CryptoStream encStream = null;
            StreamReader sr = null;
            var result = String.Empty;
            if (string.IsNullOrEmpty(sKey)) sKey = defaultDesKey;
            else if (sKey.Length > 8) sKey = sKey.Substring(0, 8);
            if (string.IsNullOrEmpty(sIv)) sIv = defaultDesIv;
            else if (sIv.Length > 8) sIv = sIv.Substring(0, 8);

            try
            {
                ms = new MemoryStream(buffer);

                var key = Encoding.UTF8.GetBytes(sKey);
                var iv = Encoding.UTF8.GetBytes(sIv);
                encStream = new CryptoStream(ms, des.CreateDecryptor(key, iv), CryptoStreamMode.Read);
                sr = new StreamReader(encStream);
                result = sr.ReadToEnd();
            }
            finally
            {
                if (sr != null)
                    sr.Close();
                if (encStream != null)
                    encStream.Close();
                if (ms != null)
                    ms.Close();
            }
            return result;
        }
        #endregion

        #endregion

        #region 3DES加密解密-DES增强版
        /// <summary> 
        /// 加密数据-3DES
        /// </summary> 
        /// <param name="input">需要加密的字符串</param> 
        /// <param name="sKey">加密秘钥,不传则默认为指定的值</param> 
        /// <param name="sIv">加密向量,不传则默认为指定的值</param> 
        /// <returns></returns> 
        public static string TripleDESEncrypt(string input, string sKey = "", string sIv = "")
        {
            if (string.IsNullOrEmpty(input))
                return String.Empty;
            if (string.IsNullOrEmpty(sKey)) sKey = defaultTripleDesKey;
            else if (sKey.Length > 32) sKey = sKey.Substring(0, 32);
            if (string.IsNullOrEmpty(sIv)) sIv = defaultTripleDesIV;
            else if (sIv.Length > 12) sIv = sIv.Substring(0, 12);

            //创建一个内存流,用于存放密文
            MemoryStream MS = new MemoryStream();

            //创建一个3DES服务提供者对象
            TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();
            TDES.Mode = CipherMode.CBC;
            TDES.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            var key = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(sKey));//先转换成散列
            var iv = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(sIv));//先转换成散列
            hashmd5.Dispose();
            //创建一个加密流,用于加密操作
            CryptoStream CS = new CryptoStream(MS,
                TDES.CreateEncryptor(key, iv),
                CryptoStreamMode.Write);

            //定义输入,执行加密操作
            CS.Write(Encoding.UTF8.GetBytes(input), 0, input.Length);
            CS.FlushFinalBlock();
            TDES.Dispose();
            //返回将密文的内存流转换为字节序列
            var decodeString = System.Convert.ToBase64String(MS.ToArray());
            CS.Close();
            return decodeString;

        }

        /// <summary> 
        /// 解密数据-3DES
        /// </summary> 
        /// <param name="input">需要加密的字符串</param> 
        /// <param name="sKey">加密秘钥,不传则默认为指定的值</param> 
        /// <param name="sIv">加密向量,不传则默认为指定的值</param> 
        /// <returns></returns> 
        public static string TripleDESDecrypt(string input, string sKey = "", string sIv = "")
        {
            if (string.IsNullOrEmpty(input))
                return String.Empty;
            if (string.IsNullOrEmpty(sKey)) sKey = defaultTripleDesKey;
            else if (sKey.Length > 32) sKey = sKey.Substring(0, 32);
            if (string.IsNullOrEmpty(sIv)) sIv = defaultTripleDesIV;
            else if (sIv.Length > 12) sIv = sIv.Substring(0, 12);

            var inputBytes = Convert.FromBase64String(input);
            //创建一个内存流,用于存放密文
            MemoryStream MS = new MemoryStream(inputBytes);

            //创建一个3DES服务提供者对象
            TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();
            TDES.Mode = CipherMode.CBC;
            TDES.Padding = PaddingMode.PKCS7;

            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            var key = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(sKey));//先转换成散列
            var iv = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(sIv));//先转换成散列
            hashmd5.Dispose();
            //创建解密流
            CryptoStream CS = new CryptoStream(MS,
                TDES.CreateDecryptor(key, iv),
                CryptoStreamMode.Read);

            //创建一个用于存放明文的容器(字节序列)
            byte[] DecrypeBytes = new byte[input.Length];

            //执行解密
            CS.Read(DecrypeBytes, 0, input.Length);
            CS.Close();
            TDES.Dispose();
            //返回解密后的明文字符串
            return Encoding.UTF8.GetString(DecrypeBytes);
        }
        #endregion

        #region AES加密解密-高级加密标准(Advanced Encryption Standard),新加密标准,用来替代DES
        /// <summary>
        /// 获取Aes32位密钥
        /// </summary>
        /// <param name="key">Aes密钥字符串</param>
        /// <returns>Aes32位密钥</returns>
        public static byte[] GetAesKey(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key", "Aes密钥不能为空");
            }
            if (key.Length < 32)
            {
                // 不足32补全
                key = key.PadRight(32, '0');
            }
            if (key.Length > 32)
            {
                key = key.Substring(0, 32);
            }
            return Encoding.UTF8.GetBytes(key);
        }
        /// <summary>
        /// Aes加密(Advanced Encryption Standard)
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="key">aes密钥,长度必须32位</param>
        /// <returns>加密后的字符串</returns>
        public static string AesEncrypt(string source, string key = "")
        {
            if (string.IsNullOrEmpty(key)) key = defaultAesKey;
            using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
            {
                aesProvider.Key = GetAesKey(key);
                aesProvider.Mode = CipherMode.ECB;
                aesProvider.Padding = PaddingMode.PKCS7;
                using (ICryptoTransform cryptoTransform = aesProvider.CreateEncryptor())
                {
                    byte[] inputBuffers = Encoding.UTF8.GetBytes(source);
                    byte[] results = cryptoTransform.TransformFinalBlock(inputBuffers, 0, inputBuffers.Length);
                    aesProvider.Clear();
                    aesProvider.Dispose();
                    return Convert.ToBase64String(results, 0, results.Length);
                }
            }
        }
        /// <summary>
        /// Aes解密(Advanced Encryption Standard)
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="key">aes密钥,长度必须32位</param>
        /// <returns>解密后的字符串</returns>
        public static string AesDecrypt(string source, string key = "")
        {
            if (string.IsNullOrEmpty(key)) key = defaultAesKey;
            using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
            {
                aesProvider.Key = GetAesKey(key);
                aesProvider.Mode = CipherMode.ECB;
                aesProvider.Padding = PaddingMode.PKCS7;
                using (ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor())
                {
                    byte[] inputBuffers = Convert.FromBase64String(source);
                    byte[] results = cryptoTransform.TransformFinalBlock(inputBuffers, 0, inputBuffers.Length);
                    aesProvider.Clear();
                    return Encoding.UTF8.GetString(results);
                }
            }
        }
        #endregion

        #region RSA加密解密、签名验证算法(对数据加密解密速度相对慢)
        /// <summary>
        /// 生成公钥、私钥对
        /// </summary>
        public static void GenerateRSAKeys()
        {
            System.Security.Cryptography.RSACryptoServiceProvider myrsa = new RSACryptoServiceProvider();
            //得到私钥主要保存了RSAParameters中的8各参数
            var privateKey = myrsa.ToXmlString(true);
            //得到公钥保存了RSAParameters中2个参数
            var publicKey = myrsa.ToXmlString(false);
        }

        /// <summary>
        /// Rsa加密
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="publicKey">RSA公钥</param>
        /// <returns>加密后的字符串</returns>
        public static string RsaEncrypt(string source, string publicKey)
        {
            //同一数据每次加密后的结果可能不同
            if (string.IsNullOrEmpty(source)) return string.Empty;
            System.Security.Cryptography.RSACryptoServiceProvider myrsa = new RSACryptoServiceProvider();
            //得到公钥
            myrsa.FromXmlString(publicKey);
            //把你要加密的内容转换成byte[]
            var PlainTextBArray = (new UnicodeEncoding()).GetBytes(source);
            //使用.NET中的Encrypt方法加密
            var CypherTextBArray = myrsa.Encrypt(PlainTextBArray, false);
            //最后吧加密后的byte[]转换成Base64String,这里就是加密后的内容了
            var res = Convert.ToBase64String(CypherTextBArray);
            return res;
        }

        /// <summary>
        /// Rsa加解密
        /// </summary>
        /// <param name="encodeStr">源字符串</param>
        /// <param name="privateKey">RSA私钥</param>
        /// <returns>解密后的字符串</returns>
        public static string RsaDecrypt(string encodeStr, string privateKey)
        {
            if (string.IsNullOrEmpty(encodeStr)) return string.Empty;
            System.Security.Cryptography.RSACryptoServiceProvider myrsa = new RSACryptoServiceProvider();
            //得到私钥
            myrsa.FromXmlString(privateKey);
            //把原来加密后的String转换成byte[]
            var PlainTextBArray = Convert.FromBase64String(encodeStr);
            //使用.NET中的Decrypt方法解密
            var DypherTextBArray = myrsa.Decrypt(PlainTextBArray, false);
            //转换解密后的byte[],这就得到了我们原来的加密前的内容了
            var res = (new UnicodeEncoding()).GetString(DypherTextBArray);
            return res;
        }

        private static byte[] getMD5Hash(string strSource)
        {
            System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
            var buffer = Encoding.UTF8.GetBytes(strSource);// System.Text.Encoding.GetEncoding("GB2312").GetBytes(strSource);
            var hashData = MD5.ComputeHash(buffer);
            return hashData;
        }

        public static string RsaSignCreate(string source, string privateKey)
        {
            //同一数据每次加密后的结果相同
            System.Security.Cryptography.RSACryptoServiceProvider MYRSA = new System.Security.Cryptography.RSACryptoServiceProvider();
            //得到私钥
            MYRSA.FromXmlString(privateKey);
            //使用.NET中提供的RSA签名,生成刚才我们的MYRSA私钥的签名对象RSAFormatter
            System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(MYRSA);
            //设置签名的算法为MD5
            RSAFormatter.SetHashAlgorithm("MD5");
            //执行签名EncryptedSignatureData就是签名后的数据
            var EncryptedSignatureData = RSAFormatter.CreateSignature(getMD5Hash(source));
            var res = Convert.ToBase64String(EncryptedSignatureData);
            return res;
        }

        public static bool RsaSignValidate(string sourceToValidate,string signedData, string publicKey)
        {
            try
            {
                System.Security.Cryptography.RSACryptoServiceProvider rsaServiceProvider = new System.Security.Cryptography.RSACryptoServiceProvider();
                //得到公钥
                rsaServiceProvider.FromXmlString(publicKey);
                //使用.NET中提供的RSA签名,生成刚才我们的MYRSA公钥的验证签名对象RSADeformatter
                System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(rsaServiceProvider);
                //指定解密的时候HASH算法为MD5
                RSADeformatter.SetHashAlgorithm("MD5");
                //验证签名
                var signedDataBytes = Convert.FromBase64String(signedData);
                bool res = RSADeformatter.VerifySignature(getMD5Hash(sourceToValidate), signedDataBytes);
                return res;
            }
            catch (FormatException ex)
            {
                return false;
            }

        }
        #endregion

    }


算法测试:

        public static void test()
        {
            string originalKey = "Pwd123$abcfghljkjkasjaskdjf";
            Console.WriteLine("DES:");
            var desEncode = EncryptHelper.DESEncrypt(originalKey, string.Empty, "GTRSQ96F");
            Console.WriteLine("原始密码:" + originalKey);
            Console.WriteLine("加密后:" + desEncode);
            var desDecode = EncryptHelper.DESDecrypt(desEncode, string.Empty, "GTRSQ96F");
            Console.WriteLine("解密后:" + desDecode);
            Console.WriteLine("3DES:");
            var tripleDesEncode = EncryptHelper.TripleDESEncrypt(originalKey);
            Console.WriteLine("加密后:" + tripleDesEncode);
            var tripleDesDecode = EncryptHelper.TripleDESDecrypt(tripleDesEncode);
            Console.WriteLine("解密后:" + tripleDesDecode);

            Console.WriteLine("AES:");
            var aesEncode = EncryptHelper.AesEncrypt(originalKey);
            Console.WriteLine("加密后:" + aesEncode);
            var aesDecode = EncryptHelper.AesDecrypt(aesEncode);
            Console.WriteLine("解密后:" + aesDecode);

            //自己先生成RSA公钥私钥存起来,参考:EncryptHelper.GenerateRSAKeys()
            var privateKey = "<RSAKeyValue><Modulus>pS7yEj3NBDAF/ZhVKK07zJzcpjKvsioGtIQdHrPHXYrJB8AdnpcaFxUbxlQb6JD73EOoJ4iRYLaxyIIt6bgvKzOWmW/WMMxcBBODpQJNPPPCL9mcQlyQy91qVTQ2qHBA7GlDcjaAw+6ZgSbXar0/qTw2z6cq/Z5rwYMjOq3Bzmk=</Modulus><Exponent>AQAB</Exponent><P>y7C0WJxCnIPPWo7c1FxYMwgSVsaCfeZhWNCTPhBF0seAlGX6JTv5xoNWtbzHs3OfWHmggFIn41Kas/kLP4OJOw==</P><Q>z5qq26OpEPntgtUpmERb6/hkMJp95Crujzzke10m4mx7DQ+po3TvcMxzIKzz50q8c2JcecUUnmtmeB/5sv0sqw==</Q><DP>O2AnMi1avYUuzJcYiE7i5v1TWzhCkbC2b81dHppfwDGnqZqQcIorJVLj09ZT4Fuz93Z88ur/9aP+tLfEL5+IQQ==</DP><DQ>DE6B5GVOR2hZcREL1y/uNw3ReqQd5GG7JJiafsml3XRK0xpjlwH+k7Q6+uvlxYdDpp9lFf7d2wpI18QlfDvP4w==</DQ><InverseQ>aSKFOP8jgKQoX8jP+RSMlPxgBnzcvF5xwA2n/0aenC3jujeFEIOLv7gEtMBC3E5FqNN6yqd1nSYRgGxoQvsa6w==</InverseQ><D>VqfrLHCpdjHvYpugyUcgIPaFttbOX0w22kqYsDumMkeVsPAzWbhxYnybZo9HWNl+l44S0DKP+cm+OK86gOs0KsEPbgxGiBpqh7c4HUzuB5Z9zsf5+GH+sTwGLNa2bRRy9HoNWOc47MfM71NNR1x1svdnXjCYNW3jJQ1EeO20d7U=</D></RSAKeyValue>";
            var publicKey = "<RSAKeyValue><Modulus>pS7yEj3NBDAF/ZhVKK07zJzcpjKvsioGtIQdHrPHXYrJB8AdnpcaFxUbxlQb6JD73EOoJ4iRYLaxyIIt6bgvKzOWmW/WMMxcBBODpQJNPPPCL9mcQlyQy91qVTQ2qHBA7GlDcjaAw+6ZgSbXar0/qTw2z6cq/Z5rwYMjOq3Bzmk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
            Console.WriteLine("RSA加密解密:");
            var rsaEncode = EncryptHelper.RsaEncrypt(originalKey, publicKey);
            Console.WriteLine("加密后:" + rsaEncode);
            var rsaDecode = EncryptHelper.RsaDecrypt(rsaEncode, privateKey);
            Console.WriteLine("解密后:" + rsaDecode);

            Console.WriteLine("RSA签名、验证:");
            var rsaSignedData = EncryptHelper.RsaSignCreate(originalKey, privateKey);
            Console.WriteLine("签名数据:" + rsaSignedData);
            var rsaResult = EncryptHelper.RsaSignValidate(originalKey, rsaSignedData, publicKey);
            Console.WriteLine(originalKey+" 验证结果:" + rsaResult);
            var originalKey2 = "abc123456";
            var rsaResult2 = EncryptHelper.RsaSignValidate(originalKey2,rsaSignedData, publicKey);
            Console.WriteLine(originalKey2 + " 验证结果:" + rsaResult2);
            Console.ReadKey();


        }


效果:



版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。