/// <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