我使用的是稍微修改过的安全类,直接来自codeproject.com,我用它来加密/解密aes字节数组。
我已经测试过,这些密钥生成方法生成相同的密钥,并且它们被赋予相同的密码和盐。他们也有相同的IV
错误总是在CryptoStream.Write
函数
AES_Decrypt
之后的行上
"未处理的类型' System.Security.Cryptography.CryptographicException'发生在mscorlib.dll
其他信息:填充无效,无法删除。"
(是的,我知道有一个静态盐是坏的,这仅用于测试目的)
Paddingmode.Zeros
Paddingmode.None
.FlushFinalBlock();
using System.Security.Cryptography;
using System.IO;
using System;
namespace FinexCore
{
public class Security
{
/*
* AES encrypt and decrypt from:
* http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt
*/
// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
private byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8}; //8 bytes
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.Padding = PaddingMode.PKCS7;
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.FlushFinalBlock();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.Padding = PaddingMode.PKCS7;
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.FlushFinalBlock();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
public void Wipe()
{
Array.Clear(saltBytes, 0, saltBytes.Length);
}
}
}
注意:使用完全相同的密码
调用保存和加载函数public void Load(byte[] password)
{
Security decryptor = new Security();
byte[] bytes = decryptor.AES_Decrypt(System.IO.File.ReadAllBytes(Pathname()), password);
using (MemoryStream stream = new MemoryStream(bytes))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Root = (Folder)binaryFormatter.Deserialize(stream);
}
Array.Clear(bytes, 0, bytes.Length);
Array.Clear(password, 0, password.Length);
decryptor.Wipe();
}
public void Save(byte[] password)
{
byte[] bytes;
using (MemoryStream stream = new MemoryStream())
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, Root);
bytes = stream.ToArray();
}
Security encryptor = new Security();
bytes = encryptor.AES_Encrypt(bytes, password);
System.IO.File.WriteAllBytes(Pathname(), bytes);
Array.Clear(bytes, 0, bytes.Length);
Array.Clear(password, 0, password.Length);
encryptor.Wipe();
}
static void keytests()
{
byte[] passwordBytes = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
byte[] saltBytes = { 1, 2, 3, 4, 5, 6, 7, 8};
int iterations = 1000;
var key1 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, iterations);
var key2 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, iterations);
Console.WriteLine(BTS(key1.GetBytes(256 / 8)));
Console.WriteLine(BTS(key2.GetBytes(256 / 8)));
}
public static string BTS(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}