【发布时间】:2015-12-16 18:57:16
【问题描述】:
我的代码执行加密但不解密。我希望它生成随机 IV,所以做了一些更改,但现在它没有解密。我想我搞砸了IV。它似乎无法正确解密。
IV 没有得到加密文件的前缀,或者解密方法无法找到 IV。我无法理解如何解决它。该文件是生成的,例如我加密了一个带有“hello world”的文本文件,加密后它产生了一些乱码。解密后生成一个空文本文件。
加密方式:
private const ushort ITERATIONS = 1300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };
private static byte[] CreateKey(string password, int keySize)
{
DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
return derivedKey.GetBytes(keySize >> 3);
}
public static void EncryptFile(string file, string password)
{
// First we are going to open the file streams
FileStream fsIn = new FileStream(file, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(file+"enc", FileMode.OpenOrCreate, FileAccess.Write);
// Then we are going to derive a Key and an IV from the
// Password and create an algorithm
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
// passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = AES.LegalKeySizes[0].MaxSize;
AES.BlockSize = AES.LegalBlockSizes[0].MaxSize;
AES.Padding = PaddingMode.Zeros;
AES.GenerateIV();
AES.Key = CreateKey(password, AES.KeySize);
AES.Mode = CipherMode.CBC;
using (MemoryStream memStream = new MemoryStream(file.Length))
memStream.Write(AES.IV, 0, 16);
CryptoStream cs = new CryptoStream(fsOut, AES.CreateEncryptor(), CryptoStreamMode.Write);
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
// read a chunk of data from the input file
bytesRead = fsIn.Read(buffer, 0, bufferLen);
// encrypt it
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
// close everything
// this will also close the unrelying fsOut stream
cs.Close();
fsIn.Close();
}
解密方法:
private const ushort ITERATIONS = 1300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };
private static byte[] CreateKey(string password, int keySize)
{
DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
return derivedKey.GetBytes(keySize >> 3);
}
public static void DecryptFile(string fileIn, string Password)
{
// First we are going to open the file streams
FileStream fsIn = new FileStream(fileIn,FileMode.Open, FileAccess.Read);
string extension = System.IO.Path.GetExtension(fileIn);
string result = fileIn.Substring(0, fileIn.Length - extension.Length);
FileStream fsOut = new FileStream(result,FileMode.OpenOrCreate, FileAccess.Write);
// passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = AES.LegalKeySizes[0].MaxSize;
AES.BlockSize = AES.LegalBlockSizes[0].MaxSize;
AES.Padding = PaddingMode.Zeros;
byte[] iv = new byte[16];
fsIn.Read(iv, 0, 16);
AES.IV=iv;
AES.Key = CreateKey(Password, AES.KeySize);
AES.Mode = CipherMode.CBC;
// Now create a crypto stream through which we are going
// to be pumping data.
// Our fileOut is going to be receiving the Decrypted bytes.
CryptoStream cs = new CryptoStream(fsOut,
AES.CreateDecryptor(), CryptoStreamMode.Write);
// Now will will initialize a buffer and will be
// processing the input file in chunks.
// This is done to avoid reading the whole file (which can be
// huge) into memory.
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
// read a chunk of data from the input file
bytesRead = fsIn.Read(buffer, 0, bufferLen);
// Decrypt it
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
// close everything
cs.Close(); // this will also close the unrelying fsOut stream
fsIn.Close();
}
【问题讨论】:
-
其实我在这里遗漏了一些东西甚至是 IV 的问题(我想要的只是 IV 应该是随机的,现在解密失败)是由于其他原因引起的错误吗?
-
您确定使用的是 128 位加密而不是 256 位吗?
-
Rijndael
LegalKeySizes[0].MaxSize是 256 位,LegalBlockSizes[0].MaxSize也是 256 位。后者是不正确的。最好指定所有值而不使用默认值。 -
您不清楚您的“解密问题”。有例外吗?如果是这样,请将它们包括在您的问题中。如果不是,则必须生成一个文件。如果是这样,该文件与您预期的文件有何不同?如果 zaph 的回答是正确的,那么前 32 个字节肯定是完全不同的,并且文件的其余部分没问题。请确认。
-
该文件是生成的,例如我加密了一个文本文件,其中包含“hello world”,加密后它产生了一些乱码。解密后生成一个空文本文件
标签: c# encryption file-io cryptography