3DES算法

   简介

                 本文基于.NET的C#实现3DES算法的加密和解密过程。可以用在加密软件、加密狗等。          代码下载链接:https://download.csdn.net/download/C_gyl/88487942

使用

  第一种方法

   加密

  1. KeySize:128(16字节),192(24字节)。
  2. Key: TripleDES 算法的密钥。
        public static string Encrypt3DES(string str, string key)
        {
            try
            {
                TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
                DES.KeySize = 128;
                DES.Key = Encoding.UTF8.GetBytes(key);
                DES.Mode = CipherMode.ECB;
                DES.Padding = PaddingMode.Zeros;
                ICryptoTransform DESEncrypt = DES.CreateEncryptor();
                byte[] Buffer = Encoding.UTF8.GetBytes(str);
                return ToHexString(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length), str.Length);
            }
            catch (Exception ex) { return ex.Message; }
        }

 解密

        public static string Decrypt3DES(string str, string key)
        {
            try
            {
                TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
                DES.Key = Encoding.UTF8.GetBytes(key);
                DES.Mode = CipherMode.ECB;
                DES.Padding = PaddingMode.Zeros;
                ICryptoTransform DESDecrypt = DES.CreateDecryptor();
                byte[] Buffer = HexGetBytes(str);
                byte[] Destxt = DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length);
                return Encoding.UTF8.GetString(Destxt, 0, Destxt.Length);
            }
            catch (Exception ex) { return ex.Message; }
        }

  转换

        // byte[]转16进制格式string 0xae00cf => "AE00CF "
        private static string ToHexString(byte[] bytes, int length)
        {
            string hexString = string.Empty;

            if (bytes != null)
            {

                StringBuilder strB = new StringBuilder();
                if (length == 0) { length = bytes.Length; }

                for (int i = 0; i < length; i++)
                {

                    strB.Append(bytes[i].ToString("X2"));

                }

                hexString = strB.ToString();

            } return hexString;

        }

        //16进制转byte[]   0x0a => 10
        private static byte[] HexGetBytes(string hexString)
        {
            int discarded = 0;
            string newString = "";
            char c;
            // remove all none A-F, 0-9, characters
            for (int i = 0; i < hexString.Length; i++)
            {
                c = hexString[i];
                if (Uri.IsHexDigit(c))
                    newString += c;
                else
                    discarded++;
            }
            // if odd number of characters, discard last character
            if (newString.Length % 2 != 0)
            {
                discarded++;
                newString = newString.Substring(0, newString.Length - 1);
            }

            int byteLength = newString.Length / 2;
            byte[] bytes = new byte[byteLength];
            string hex;
            int j = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                hex = new String(new Char[] { newString[j], newString[j + 1] });
                bytes[i] = HexToByte(hex);
                j = j + 2;
            }
            return bytes;
        }

        private static byte HexToByte(string hex)
        {
            byte tt = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
            return tt;
        }

  第二种方法

  1. 第一种方法有个弊端是.Net会对密钥Key进行判断,例如key="0000000000000000",会有报警"指定密钥是“TripleDES”的已知弱密钥,不能使用。" .Net方法(TripleDES.IsWeakKey),它检查3DES密钥的弱点。
  2. 解释弱密钥参考:Decrypting TripleDES:指定的密钥是已知的弱密钥,不能使用 - VoidCC
  3. 破解若密钥参考:https://www.cnblogs.com/jintianhu/archive/2011/11/26/2264375.html

  加密

        public static string DESEncrypt(string str, string key)
        {
            try
            {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

                des.Padding = PaddingMode.Zeros;
                byte[] keyByte = Encoding.UTF8.GetBytes(key);

                Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode");
                object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t);

                MethodInfo mi = des.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic);
                ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(des, new object[] { keyByte, CipherMode.ECB, null, 0, obj });


                byte[] Buffer = Encoding.UTF8.GetBytes(str);
                byte[] result = desCrypt.TransformFinalBlock(Buffer, 0, Buffer.Length);
                return BitConverter.ToString(result).Replace("-", "");
            }
            catch (Exception ex) { return ex.Message; }
        }

  解密

        public static string DESDecrypt(string str, string key)
        {
            try
            {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

                des.Padding = PaddingMode.Zeros;
                byte[] keyByte = Encoding.UTF8.GetBytes(key);

                Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode");
                object obj = t.GetField("Decrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t);

                MethodInfo mi = des.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic);
                ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(des, new object[] { keyByte, CipherMode.ECB, null, 0, obj });

                byte[] Buffer = HexGetBytes(str);
                byte[] Destxt = desCrypt.TransformFinalBlock(Buffer, 0, Buffer.Length);
                return Encoding.UTF8.GetString(Destxt, 0, Destxt.Length);
            }
            catch (Exception ex) { return ex.Message; }
        }

结果 

        static void Main(string[] args)
        {
            string str = "12345678";//长度是8的倍数
            string key = "1234567812345678"; //长度是16或24

            //第一种方法
            //有密钥检测
            //"指定密钥是“TripleDES”的已知弱密钥,不能使用。"
            string strEncrypt1 = Encrypt3DES(str, key);
            System.Console.WriteLine("加密结果1:" + strEncrypt1);
            string strDecrypt1 = Decrypt3DES(strEncrypt1, key);
            System.Console.WriteLine("解密结果1:" + strDecrypt1);

            //第二种方法
            //无弱密钥检测
            string strEncrypt2 = DESEncrypt(str, key);
            System.Console.WriteLine("加密结果2:" + strEncrypt2);
            string strDecrypt2 = DESDecrypt(strEncrypt2, key);
            System.Console.WriteLine("解密结果2:" + strDecrypt2);

            Console.ReadKey();
        }

 key = "1234567890123456"

 key = "1234567812345678"

你可能感兴趣的:(杂项,3DES,算法,C#)