DES加密解密类 生成Hex密文或Base64密文(C#版本)

我们经常在开发中要对字符串进行加密,解密,下面是我经常用到的DES加密和解密方法,可以根据自己的需求选择DES的不同加密模式和填充模式,这里提供两种加密结果方法,一种是返回HEX加密字符串,这个字符串不包含特殊字符,密文全部是由字母和数字组成,非常适用某些特殊场景,也是我特别喜欢的一种加密结果,不需要考虑特殊字符问题;还一种就是最常见的加密结果Base64字符串,不多说了,直接上代码

加密解密使用方法如下:
    /// <summary>
    /// 文章来源于成长的小猪
    /// http://blog.csdn.net/jasonsong2008
    /// </summary>
    [TestFixture()]
    public class DesHelperTests
    {

        //待加密的字符串
        const string Str = "成长的小猪(Jason.Song)http://blog.csdn.net/jasonsong2008 ";
        //密钥(限定8位任意字符)用于加解密
        const string Key = "jason!@#";

        /// <summary>
        /// 加解密测试(Hex)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// 此加密方法生成 Hex 字符串,这个有点好就是加密后字符串中不包含特殊字符,适用于特殊场景
        /// </summary>
        [Test()]
        public void EncryptToHexStringTest() {

            var ciphertext = DesHelper.EncryptToHexString(Str, Key, Encoding.UTF8);
            //var ciphertext = DesHelper.EncryptToHexString(str, key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
            Console.Out.WriteLine(ciphertext);

            //加密后输出结果如下
            //754B1591AEDD6056545731496E78E335554746E7F2A8F95C28228420DD3A6F701F8E708E2601B673416455E30065FE1FD75E36494A6910DD03BE3413170F732783361E15BCFCD4B8

            //解密方法
            var plaintext = DesHelper.DecryptByHexString(ciphertext, Key, Encoding.UTF8);
            //var plaintext = DesHelper.DecryptByHexString(ciphertext, key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
            Console.Out.WriteLine(plaintext);

            Assert.AreEqual(Str, plaintext);
        }

        /// <summary>
        /// 加解密测试(Base64)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// 此加密方法生成 Base64 字符串,该用法最常见
        /// </summary>
        [Test()]
        public void EncryptToBase64StringTest() {

            //加密方法
            var ciphertext = DesHelper.EncryptToBase64String(Str, Key, Encoding.UTF8);
            //var ciphertext = DesHelper.EncryptToBase64String(Str, Key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
            Console.Out.WriteLine(ciphertext);

            //加密后输出结果如下
            //dUsVka7dYFZUVzFJbnjjNVVHRufyqPlcKCKEIN06b3AfjnCOJgG2c0FkVeMAZf4f1142SUppEN0DvjQTFw9zJ4M2HhW8/NS4

            //解密方法
            var plaintext = DesHelper.DecryptByBase64String(ciphertext, Key, Encoding.UTF8);
            //var plaintext = DesHelper.DecryptByBase64String(ciphertext, Key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
            Console.Out.WriteLine(plaintext);

            Assert.AreEqual(Str, plaintext);
        }
    }

下面是DES的加密解密类

    /// <summary>
    /// DES加解密
    /// Add by 成长的小猪(Jason.Song) on 2017/11/20
    /// http://blog.csdn.net/jasonsong2008
    /// 
    /// DES是对称性加密里面常见一种,全称为Data Encryption Standard,即数据加密标准,
    /// 是一种使用密钥加密的块算法。密钥长度是64位(bit),超过位数密钥被忽略。
    /// 所谓对称性加密,加密和解密密钥相同。对称性加密一般会按照固定长度,把待加密字符串分成块。
    /// 不足一整块或者刚好最后有特殊填充字符。往往跨语言做DES加密解密,经常会出现问题。
    /// 往往是填充方式不对、或者编码不一致、或者选择加密解密模式(ECB,CBC,CTR,OFB,CFB,NCFB,NOFB)没有对应上造成。
    /// 常见的填充模式有: 'pkcs5','pkcs7','iso10126','ansix923','zero' 类型,
    /// 包括DES-ECB,DES-CBC,DES-CTR,DES-OFB,DES-CFB。 
    /// </summary>
    public static class DesHelper
    {
        #region DES 加密

        /// <summary>
        /// 加密(Hex)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥(8位任意字符)</param>
        /// <param name="encoding">字符编码</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static string EncryptToHexString(string encryptString, string encryptKey, Encoding encoding,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            //为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
            //var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
            var keyBytes = encoding.GetBytes(encryptKey);
            var inputBytes = encoding.GetBytes(encryptString);
            var outputBytes = EncryptToDesBytes(inputBytes, keyBytes, cipher, padding);
            var sBuilder = new StringBuilder();
            foreach (var b in outputBytes) {
                sBuilder.Append(b.ToString("X2"));
            }
            return sBuilder.ToString();
        }

        /// <summary>
        /// 加密(Base64)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥(8位任意字符)</param>
        /// <param name="encoding">字符编码</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static string EncryptToBase64String(string encryptString, string encryptKey, Encoding encoding,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            //为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
            //var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
            var keyBytes = encoding.GetBytes(encryptKey);
            var inputBytes = encoding.GetBytes(encryptString);
            var outputBytes = EncryptToDesBytes(inputBytes, keyBytes, cipher, padding);
            return Convert.ToBase64String(outputBytes);
        }

        /// <summary>
        /// 加密
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="encryptBytes">待加密的字节数组</param>
        /// <param name="keyBytes">加密密钥字节数组</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static byte[] EncryptToDesBytes(byte[] encryptBytes, byte[] keyBytes,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            var des = new DESCryptoServiceProvider {
                Key = keyBytes,
                IV = keyBytes,
                Mode = cipher,
                Padding = padding
            };
            var outputBytes = des.CreateEncryptor().TransformFinalBlock(encryptBytes, 0, encryptBytes.Length);
            return outputBytes;
        }

        #endregion

        #region DES 解密

        /// <summary>
        /// 解密(Hex)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥(8位任意字符)</param>
        /// <param name="encoding">字符编码</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static string DecryptByHexString(string decryptString, string decryptKey, Encoding encoding,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            //为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
            //var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
            var keyBytes = encoding.GetBytes(decryptKey);
            var inputBytes = new byte[decryptString.Length / 2];
            for (var i = 0; i < inputBytes.Length; i++) {
                inputBytes[i] = Convert.ToByte(decryptString.Substring(i * 2, 2), 16);
            }
            var outputBytes = DecryptByDesBytes(inputBytes, keyBytes, cipher, padding);
            return encoding.GetString(outputBytes).TrimEnd('\0');
        }

        /// <summary>
        /// 解密(Base64)
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥(8位任意字符)</param>
        /// <param name="encoding">字符编码</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static string DecryptByBase64String(string decryptString, string decryptKey, Encoding encoding,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            //为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
            //var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
            var keyBytes = encoding.GetBytes(decryptKey);
            var inputBytes = Convert.FromBase64String(decryptString);
            var outputBytes = DecryptByDesBytes(inputBytes, keyBytes, cipher, padding);
            return encoding.GetString(outputBytes).TrimEnd('\0');
        }

        /// <summary>
        /// 解密
        /// Add by 成长的小猪(Jason.Song) on 2017/07/26
        /// </summary>
        /// <param name="decryptBytes">待解密的字节数组</param>
        /// <param name="keyBytes">解密密钥字节数组</param>
        /// <param name="cipher">运算模式</param>
        /// <param name="padding">填充模式</param>
        /// <returns></returns>
        public static byte[] DecryptByDesBytes(byte[] decryptBytes, byte[] keyBytes,
            CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
            var des = new DESCryptoServiceProvider {
                Key = keyBytes,
                IV = keyBytes,
                Mode = cipher,
                Padding = padding
            };
            var outputBytes = des.CreateDecryptor().TransformFinalBlock(decryptBytes, 0, decryptBytes.Length);
            return outputBytes;
        }

        #endregion


    }

猜你喜欢

转载自blog.csdn.net/jasonsong2008/article/details/80077517