C#实现AES算法

AES算法是什么,这里就没有必要多说了。
这是曾经的一个小项目用到的,貌似也没有几行代码。
我不清楚这个是不是标准的AES算法,但是我要的目的已经实现了。
反正我也不是多么重要的数据,只要能实现不能反向解密就足够了。

首先要准备下面几个常量

1
2
3
4
5
6
7
8
9
//VI初始向量,这个可以自定义,但是每个元素都是16进制,也就是说只能是0-9数字和A-F字母的组合,而且元素数量必须是16个。
private static byte[] _key= { 0x32, 0x08, 0x30, 0x09, 0xA3, 0x06, 0xB9, 0x07, 0xB9, 0x1F, 0x12, 0x03, 0xC9, 0x17, 0x8A, 0x36 };
//加密和解密Key
private static string strKey = "ywmt";

private static string salt = "SomeString";
//最后这个参数其实不是必须的,只是我为了测试的时候,加入进去增加混淆。
//如果设置了这个参数,那么待加密的字符串会在末尾(或者其他位置)加入这个字符串,然后才对新的字符串加密。
//解密的时候,得到的结果需要减去这个字符串才是正确的结果。因此待加密的字符串一定不能与salt的值相同。

然后下面是加密算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
/// AES加密算法
/// </summary>
/// <param name="str">需要加密的字符串</param>
/// <returns>加密后的字符串</returns>
public static string AESEncrypt(string str)
{
//下面这就是连接字符串的混淆,如果不设置salt,可以省略这一步
str = str + salt;
SymmetricAlgorithm aes = Rijndael.Create();
byte[] inputByte = Encoding.UTF8.GetBytes(str);
//Key必须是16位,所以用MD5算法得到小写的16位的字符串
aes.Key = Encoding.UTF8.GetBytes(getMd5(strKey));
aes.IV = _key;
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByte, 0, inputByte.Length);
cs.FlushFinalBlock();
byte[] cipher = ms.ToArray();
cs.Close();
ms.Close();
return Convert.ToBase64String(cipher);
}

这里返回的加密后的字符串。

最后是解密算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
/// AES解密算法
/// </summary>
/// <param name="cipher">需要解密的字符串</param>
/// <returns>解密后的字符串</returns>
public static string AESDecrypt(string cipher)
{
SymmetricAlgorithm aes = Rijndael.Create();
byte[] inputCipher = Convert.FromBase64String(cipher);
aes.Key = Encoding.UTF8.GetBytes(getMd5(strKey));
aes.IV = _key;
byte[] decryptBytes = new byte[inputCipher.Length];
MemoryStream ms = new MemoryStream(inputCipher);
CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read);
cs.Read(decryptBytes, 0, decryptBytes.Length);
cs.Close();
ms.Close();
string re = Encoding.UTF8.GetString(decryptBytes).Replace("\0", "");
//因为解密后的结果不知道为什么会加上一个“\0”,所以需要删除

//返回字符串之前,要把salt值删除,如果没有设置salt值,可以直接返回re
return re.Replace(salt, "");
}

一些说明

  • 加入salt后,即使待加密的字符串只有一位,也可以得到较长的加密结果,迷惑他人。
  • 加密结果类似这样OtXJ4bLfuefNA6viw0zrBFUkyyGT2MjS8tOE5JK0yJRenM1WZZmp6xlgyY/d4dXb
  • C#接触的比较多,所以就老是用C#写一些小程序