黄聪:【转】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

    原文作者:加密算法
    原文地址: http://www.cnblogs.com/huangcong/archive/2010/05/18/1738668.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞