zoukankan      html  css  js  c++  java
  • 黄聪:【转】C# 对称加密解密算法

        /// <summary>
        /// 对称加密算法类,使用系统自带的函数
        /// </summary>
        public class SymmetricMethod
        {

            private SymmetricAlgorithm mobjCryptoService;
            private string Key;
            /// <summary>
            /// 对称加密类的构造函数
            /// </summary>
            public SymmetricMethod()
            {
                mobjCryptoService = new RijndaelManaged();
                Key = "Guz(%&hj7x89H$yuBI0456FtmaT5&fvHUFCy76*h%(HilJ$lhj!y6&(*jkP87jH7";
            }
            /// <summary>
            /// 获得密钥
            /// </summary>
            /// <returns>密钥</returns>
            private byte[] GetLegalKey()
            {
                string sTemp = Key;
                mobjCryptoService.GenerateKey();
                byte[] bytTemp = mobjCryptoService.Key;
                int KeyLength = bytTemp.Length;
                if (sTemp.Length > KeyLength)
                    sTemp = sTemp.Substring(0, KeyLength);
                else if (sTemp.Length < KeyLength)
                    sTemp = sTemp.PadRight(KeyLength, ' ');
                return ASCIIEncoding.ASCII.GetBytes(sTemp);
            }
            /// <summary>
            /// 获得初始向量IV
            /// </summary>
            /// <returns>初试向量IV</returns>
            private byte[] GetLegalIV()
            {
                string sTemp = "E4ghj*Ghg7!rNIfb&95GUY86GfghUb#er57HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";
                mobjCryptoService.GenerateIV();
                byte[] bytTemp = mobjCryptoService.IV;
                int IVLength = bytTemp.Length;
                if (sTemp.Length > IVLength)
                    sTemp = sTemp.Substring(0, IVLength);
                else if (sTemp.Length < IVLength)
                    sTemp = sTemp.PadRight(IVLength, ' ');
                return ASCIIEncoding.ASCII.GetBytes(sTemp);
            }
            /// <summary>
            /// 加密方法
            /// </summary>
            /// <param name="Source">待加密的串</param>
            /// <returns>经过加密的串</returns>
            public string Encrypto(string Source)
            {
                byte[] bytIn = UTF8Encoding.UTF8.GetBytes(Source);
                MemoryStream ms = new MemoryStream();
                mobjCryptoService.Key = GetLegalKey();
                mobjCryptoService.IV = GetLegalIV();
                ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
                cs.Write(bytIn, 0, bytIn.Length);
                cs.FlushFinalBlock();
                ms.Close();
                byte[] bytOut = ms.ToArray();
                return Convert.ToBase64String(bytOut);
            }
            /// <summary>
            /// 解密方法
            /// </summary>
            /// <param name="Source">待解密的串</param>
            /// <returns>经过解密的串</returns>
            public string Decrypto(string Source)
            {
                byte[] bytIn = Convert.FromBase64String(Source);
                MemoryStream ms = new MemoryStream(bytIn, 0, bytIn.Length);
                mobjCryptoService.Key = GetLegalKey();
                mobjCryptoService.IV = GetLegalIV();
                ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cs);
                return sr.ReadToEnd();
            }
        }

    ///////////手动自己写的对称加密方法

        enum TDesMode { dmEncry, dmDecry };

        public class Des
        {
            static readonly byte[] BitIP =
        {
          57, 49, 41, 33, 25, 17,  9,  1,
          59, 51, 43, 35, 27, 19, 11,  3,
          61, 53, 45, 37, 29, 21, 13,  5,
          63, 55, 47, 39, 31, 23, 15,  7,
          56, 48, 40, 32, 24, 16,  8,  0,
          58, 50, 42, 34, 26, 18, 10,  2,
          60, 52, 44, 36, 28, 20, 12,  4,
          62, 54, 46, 38, 30, 22, 14,  6
        };

            static readonly byte[] BitCP =
        {
          39,  7, 47, 15, 55, 23, 63, 31,
          38,  6, 46, 14, 54, 22, 62, 30,
          37,  5, 45, 13, 53, 21, 61, 29,
          36,  4, 44, 12, 52, 20, 60, 28,
          35,  3, 43, 11, 51, 19, 59, 27,
          34,  2, 42, 10, 50, 18, 58, 26,
          33,  1, 41,  9, 49, 17, 57, 25,
          32,  0, 40,  8, 48, 16, 56, 24
        };

            static readonly int[] BitExp =
        {
          31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
          11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
          21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0
        };

            static readonly byte[] BitPM =
        {
          15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
           1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24
        };

            static readonly byte[,] sBox =
        {
          {
            14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
             0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
             4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
            15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13
          },
          {
            15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
             3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
             0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
            13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9
          },
          {
            10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
            13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
            13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
             1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12
          },
          {
             7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
            13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
            10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
             3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14
          },
          {
             2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
            14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
             4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
            11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3
          },
          {
            12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
            10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
             9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
             4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13
          },
          {
             4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
            13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
             1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
             6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12
          },
          {
            13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
             1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
             7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
             2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
          }
        };

            static readonly byte[] BitPMC1 =
        {
          56, 48, 40, 32, 24, 16,  8,
           0, 57, 49, 41, 33, 25, 17,
           9,  1, 58, 50, 42, 34, 26,
          18, 10,  2, 59, 51, 43, 35,
          62, 54, 46, 38, 30, 22, 14,
           6, 61, 53, 45, 37, 29, 21,
          13,  5, 60, 52, 44, 36, 28,
          20, 12,  4, 27, 19, 11,  3
        };

            static readonly byte[] BitPMC2 =
        {
          13, 16, 10, 23,  0,  4,
           2, 27, 14,  5, 20,  9,
          22, 18, 11,  3, 25,  7,
          15,  6, 26, 19, 12,  1,
          40, 51, 30, 36, 46, 54,
          29, 39, 50, 44, 32, 47,
          43, 48, 38, 55, 33, 52,
          45, 41, 49, 35, 28, 31
        };

            byte[][] SubKey;

            string Key;


            public Des()
            {
                Key = "Guz(%&hj7x89H$yuBI0456FtmaT5&fvHUFCy76*h%(HilJ$lhj!y6&(*jkP87jH7";
                SubKey = new byte[16][];
                for (int i = 0; i < SubKey.Length; i++)
                {
                    SubKey[i] = new byte[6];
                }
            }

            void initPermutation(byte[] inData)
            {
                byte[] newData = new byte[8];
                for (int i = 0; i < 64; i++)
                {
                    if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)
                    {
                        newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
                Array.Copy(newData, inData, 8);
            }

            void conversePermutation(byte[] inData)
            {
                byte[] newData = new byte[8];
                for (int i = 0; i < 64; i++)
                {
                    if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)
                    {
                        newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
                Array.Copy(newData, inData, 8);
            }

            void expand(byte[] inData, byte[] outData)
            {
                Array.Clear(outData, 0, 6);
                for (int i = 0; i < 48; i++)
                {
                    if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)
                    {
                        outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
            }

            void permutation(byte[] inData)
            {
                byte[] newData = new byte[4];
                for (int i = 0; i < 32; i++)
                {
                    if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)
                    {
                        newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
                Array.Copy(newData, inData, 4);
            }

            byte si(byte s, byte inByte)
            {
                int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);
                return (byte)(sBox[s, c] & 0x0f);
            }

            void permutationChoose1(byte[] inData, byte[] outData)
            {
                Array.Clear(outData, 0, 7);
                for (int i = 0; i < 56; i++)
                {
                    if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
                    {
                        outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
            }

            void permutationChoose2(byte[] inData, byte[] outData)
            {
                Array.Clear(outData, 0, 6);
                for (int i = 0; i < 48; i++)
                {
                    if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
                    {
                        outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
                    }
                }
            }

            void cycleMove(byte[] inData, byte bitMove)
            {
                for (int i = 0; i < bitMove; i++)
                {
                    inData[0] = (byte)((inData[0] << 1) | (inData[1] >> 7));
                    inData[1] = (byte)((inData[1] << 1) | (inData[2] >> 7));
                    inData[2] = (byte)((inData[2] << 1) | (inData[3] >> 7));
                    inData[3] = (byte)((inData[3] << 1) | ((inData[0] & 0x10) >> 4));
                    inData[0] = (byte)(inData[0] & 0x0f);
                }
            }

            static readonly byte[] bitDisplace = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };

            void makeKey(byte[] inKey, byte[][] outKey)
            {
                byte[] outData56 = new byte[7];
                byte[] key28l = new byte[4];
                byte[] key28r = new byte[4];
                byte[] key56o = new byte[7];

                permutationChoose1(inKey, outData56);
                key28l[0] = (byte)(outData56[0] >> 4);
                key28l[1] = (byte)((outData56[0] << 4) | (outData56[1] >> 4));
                key28l[2] = (byte)((outData56[1] << 4) | (outData56[2] >> 4));
                key28l[3] = (byte)((outData56[2] << 4) | (outData56[3] >> 4));
                key28r[0] = (byte)(outData56[3] & 0x0f);
                key28r[1] = (byte)(outData56[4]);
                key28r[2] = (byte)(outData56[5]);
                key28r[3] = (byte)(outData56[6]);

                for (int i = 0; i < 16; i++)
                {
                    cycleMove(key28l, bitDisplace[i]);
                    cycleMove(key28r, bitDisplace[i]);
                    key56o[0] = (byte)((key28l[0] << 4) | (key28l[1] >> 4));
                    key56o[1] = (byte)((key28l[1] << 4) | (key28l[2] >> 4));
                    key56o[2] = (byte)((key28l[2] << 4) | (key28l[3] >> 4));
                    key56o[3] = (byte)((key28l[3] << 4) | (key28r[0]));
                    key56o[4] = (byte)(key28r[1]);
                    key56o[5] = (byte)(key28r[2]);
                    key56o[6] = (byte)(key28r[3]);
                    permutationChoose2(key56o, outKey[i]);
                };
            }

            void encry(byte[] inData, byte[] subKey, byte[] outData)
            {
                byte[] outBuf = new byte[6];
                byte[] buf = new byte[8];

                expand(inData, outBuf);
                for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);
                // outBuf  xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
                buf[0] = (byte)(outBuf[0] >> 2);                               //xxxxxx -> 2
                buf[1] = (byte)(((outBuf[0] & 0x03) << 4) | (outBuf[1] >> 4)); // 4 <- xx xxxx -> 4
                buf[2] = (byte)(((outBuf[1] & 0x0f) << 2) | (outBuf[2] >> 6)); //        2 <- xxxx xx -> 6
                buf[3] = (byte)(outBuf[2] & 0x3f);                             //                    xxxxxx
                buf[4] = (byte)(outBuf[3] >> 2);                               //                           xxxxxx
                buf[5] = (byte)(((outBuf[3] & 0x03) << 4) | (outBuf[4] >> 4)); //                                 xx xxxx
                buf[6] = (byte)(((outBuf[4] & 0x0f) << 2) | (outBuf[5] >> 6)); //                                        xxxx xx
                buf[7] = (byte)(outBuf[5] & 0x3f);                             //                                               xxxxxx
                for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);
                for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i * 2] << 4) | buf[i * 2 + 1]);
                permutation(outBuf);
                for (int i = 0; i < 4; i++) outData[i] = outBuf[i];
            }

            // inData, outData 都为 8 Bytes,否则出错
            void desData(TDesMode desMode, byte[] inData, byte[] outData)
            {
                int i, j;
                byte[] temp = new byte[4];
                byte[] buf = new byte[4];

                for (i = 0; i < 8; i++) outData[i] = inData[i];
                initPermutation(outData);
                if (desMode == TDesMode.dmEncry)
                {
                    for (i = 0; i < 16; i++)
                    {
                        for (j = 0; j < 4; j++) temp[j] = outData[j];                     //temp = Ln
                        for (j = 0; j < 4; j++) outData[j] = outData[j + 4];                //Ln+1 = Rn
                        encry(outData, SubKey[i], buf);                                   //Rn ==Kn==> buf
                        for (j = 0; j < 4; j++) outData[j + 4] = (byte)(temp[j] ^ buf[j]);  //Rn+1 = Ln^buf
                    };
                    for (j = 0; j < 4; j++) temp[j] = outData[j + 4];
                    for (j = 0; j < 4; j++) outData[j + 4] = outData[j];
                    for (j = 0; j < 4; j++) outData[j] = temp[j];
                }
                else if (desMode == TDesMode.dmDecry)
                {
                    for (i = 15; i >= 0; i--)
                    {
                        for (j = 0; j < 4; j++) temp[j] = outData[j];
                        for (j = 0; j < 4; j++) outData[j] = outData[j + 4];
                        encry(outData, SubKey[i], buf);
                        for (j = 0; j < 4; j++) outData[j + 4] = (byte)(temp[j] ^ buf[j]);
                    };
                    for (j = 0; j < 4; j++) temp[j] = outData[j + 4];
                    for (j = 0; j < 4; j++) outData[j + 4] = outData[j];
                    for (j = 0; j < 4; j++) outData[j] = temp[j];
                };
                conversePermutation(outData);
            }

            byte[] Redim(byte[] arr, int newSize)
            {
                if (newSize == arr.Length) return arr;
                byte[] newArr = new byte[newSize];
                Array.Copy(arr, 0, newArr, 0, Math.Min(arr.Length, newSize));
                return newArr;
            }

            /**/
            //////////////////////////////////////////////////////////////

            public byte[] EncryBytes(byte[] inData, byte[] keyByte)
            {
                byte[] tmpByte = new byte[8];
                byte[] outByte = new byte[8];

                if ((inData.Length > 0) && (inData[inData.Length - 1] == 0))
                {
                    throw new ArgumentException("The last byte is 0.", "inData");
                }
                if (inData.Length % 8 != 0) inData = Redim(inData, (inData.Length + 7) / 8 * 8);
                if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
                makeKey(keyByte, SubKey);

                byte[] outData = new byte[inData.Length];
                for (int i = 0; i < inData.Length / 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        tmpByte[j] = inData[i * 8 + j];
                    }
                    desData(TDesMode.dmEncry, tmpByte, outByte);
                    for (int j = 0; j < 8; j++)
                    {
                        outData[i * 8 + j] = outByte[j];
                    }
                };

                return outData;
            }

            public byte[] DecryBytes(byte[] inData, byte[] keyByte)
            {
                byte[] tmpByte = new byte[8];
                byte[] outByte = new byte[8];

                if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
                makeKey(keyByte, SubKey);

                byte[] outData = new byte[(inData.Length + 7) / 8 * 8];
                for (int i = 0; i < inData.Length / 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        tmpByte[j] = inData[i * 8 + j];
                    }
                    desData(TDesMode.dmDecry, tmpByte, outByte);
                    for (int j = 0; j < 8; j++)
                    {
                        outData[i * 8 + j] = outByte[j];
                    }
                };

                int n = outData.Length - 1;
                while (n >= 0 && outData[n] == 0) --n;
                return Redim(outData, n + 1);
            }

            public string EncryStr(string Str)
            {
                byte[] inData = Encoding.UTF8.GetBytes(Str);
                byte[] keyByte = Encoding.UTF8.GetBytes(Key);
                byte[] tmpByte = EncryBytes(inData, keyByte);
                StringBuilder tmpStr = new StringBuilder();
                foreach (byte b in tmpByte)
                {
                    tmpStr.Append((char)b);
                }
                return tmpStr.ToString();
            }

            public string DecryStr(string Str)
            {
                byte[] inData = new byte[Str.Length];
                for (int i = 0; i < Str.Length; i++)
                {
                    inData[i] = (byte)Str[i];
                }
                byte[] keyByte = Encoding.UTF8.GetBytes(Key);
                byte[] tmpByte = DecryBytes(inData, keyByte);
                return Encoding.UTF8.GetString(tmpByte);
            }

            public string EncryStrHex(string Str)
            {
                byte[] inData = Encoding.UTF8.GetBytes(Str);
                byte[] keyByte = Encoding.UTF8.GetBytes(Key);
                byte[] tmpByte = EncryBytes(inData, keyByte);
                StringBuilder tmpStr = new StringBuilder();
                foreach (byte b in tmpByte)
                {
                    tmpStr.AppendFormat("{0:X2}", b);
                }
                return tmpStr.ToString();
            }

            public string DecryStrHex(string StrHex)
            {
                if (StrHex.Length % 2 != 0)
                {
                    throw new ArgumentException("String length must be even.", "StrHex");
                }
                byte[] inData = new byte[StrHex.Length / 2];
                for (int i = 0; i < StrHex.Length; i += 2)
                {
                    inData[i / 2] = (byte)(Uri.FromHex(StrHex[i]) * 16 + Uri.FromHex(StrHex[i + 1]));
                }
                byte[] keyByte = Encoding.UTF8.GetBytes(Key);
                byte[] tmpByte = DecryBytes(inData, keyByte);
                return Encoding.UTF8.GetString(tmpByte);
            }
        }// End of class Des

  • 相关阅读:
    第二十章 用户管理(一)
    第十九章 Linux中常用字符的特殊含义
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
  • 原文地址:https://www.cnblogs.com/huangcong/p/1738668.html
Copyright © 2011-2022 走看看