用 aes 加密后我的文件长了一个块
after encrypting with aes my file is one block longer
我正在使用 AES 加密模式 CBC 和默认填充(我没有设置它,所以我猜它会设置默认填充模式)。
当我尝试以 example/test 的身份加密一个 .txt 文件时,只写了几个字(将其视为 50 个字节);输出文件高出一个块,因此,例如 4096+16=5012。我猜这是因为它读取了一个完整的 4096 字节块,对其进行编码并写入。但是后来他添加了 16 个额外的字节,不知道为什么;因为填充应该填充一个块。
我的代码是:
using (Aes myAes = Aes.Create())
{
myAes.BlockSize = myAes.LegalBlockSizes[0].MaxSize;
myAes.KeySize = myAes.LegalKeySizes[0].MaxSize;
myAes.Mode = CipherMode.CBC;
myAes.GenerateIV();
myAes.GenerateKey();
ICryptoTransform encryptor = myAes.CreateEncryptor(myAes.Key, myAes.IV );
CryptoStream csCrypt = new CryptoStream(FileOUT, encryptor, CryptoStreamMode.Write);
do
{
bytesRead = FileIN.Read(buffer, 0, bufferLen);
if (bytesRead != 0)
{
csCrypt.Write(buffer, 0, bufferLen);
}
} while (bytesRead != 0);
csCrypt.Close();
csCrypt.Dispose();
FileIN.Close();
FileIN.Dispose();
FileOUT.Close();
FileOUT.Dispose();
}
是吗?有什么方法可以修复添加的 16 个额外字节吗?
具有 CBC 或 ECB 等操作模式的 AES 仅适用于完整块(16 字节的倍数),这就是需要填充的原因。当明文已经是块大小的倍数时,则必须添加额外的填充块,否则你不知道解密后要删除多少字节。
由于 4096 字节是块大小的倍数,因此添加了一个完整的填充块,然后对所有内容进行加密,得到 5012 个密文字节。
这就是 PKCS#7 填充的运作方式(有时称为 PKCS#5 填充)。如果你能确定你总是读取块大小的倍数的字节,那么你可以设置
myAes.Padding = PaddingMode.None;
用于加密和解密。
由于您使用的是带有随机生成的 IV 的 CBC 模式,因此您需要将其存储在某个地方。将 IV 写在密文的开头通常是个好主意,这样您就不必通过其他方式跟踪它。不一定要保密,只要不可预测即可。
我正在使用 AES 加密模式 CBC 和默认填充(我没有设置它,所以我猜它会设置默认填充模式)。
当我尝试以 example/test 的身份加密一个 .txt 文件时,只写了几个字(将其视为 50 个字节);输出文件高出一个块,因此,例如 4096+16=5012。我猜这是因为它读取了一个完整的 4096 字节块,对其进行编码并写入。但是后来他添加了 16 个额外的字节,不知道为什么;因为填充应该填充一个块。
我的代码是:
using (Aes myAes = Aes.Create())
{
myAes.BlockSize = myAes.LegalBlockSizes[0].MaxSize;
myAes.KeySize = myAes.LegalKeySizes[0].MaxSize;
myAes.Mode = CipherMode.CBC;
myAes.GenerateIV();
myAes.GenerateKey();
ICryptoTransform encryptor = myAes.CreateEncryptor(myAes.Key, myAes.IV );
CryptoStream csCrypt = new CryptoStream(FileOUT, encryptor, CryptoStreamMode.Write);
do
{
bytesRead = FileIN.Read(buffer, 0, bufferLen);
if (bytesRead != 0)
{
csCrypt.Write(buffer, 0, bufferLen);
}
} while (bytesRead != 0);
csCrypt.Close();
csCrypt.Dispose();
FileIN.Close();
FileIN.Dispose();
FileOUT.Close();
FileOUT.Dispose();
}
是吗?有什么方法可以修复添加的 16 个额外字节吗?
具有 CBC 或 ECB 等操作模式的 AES 仅适用于完整块(16 字节的倍数),这就是需要填充的原因。当明文已经是块大小的倍数时,则必须添加额外的填充块,否则你不知道解密后要删除多少字节。
由于 4096 字节是块大小的倍数,因此添加了一个完整的填充块,然后对所有内容进行加密,得到 5012 个密文字节。
这就是 PKCS#7 填充的运作方式(有时称为 PKCS#5 填充)。如果你能确定你总是读取块大小的倍数的字节,那么你可以设置
myAes.Padding = PaddingMode.None;
用于加密和解密。
由于您使用的是带有随机生成的 IV 的 CBC 模式,因此您需要将其存储在某个地方。将 IV 写在密文的开头通常是个好主意,这样您就不必通过其他方式跟踪它。不一定要保密,只要不可预测即可。