您需要知道使用 aes 加密的输出的大小。
在网上找到公式
int endSize = (startSize / 16) * 16 + (startSize%16 == 0 ? 0 : 16)
逻辑很清楚 - 如果大小不适合 aes 块的倍数(即 16 字节),那么我们对齐到倍数。然而,事实证明,一个更正确的公式
int endSize = (startSize / 16) * 16 + 16
测试用例:
var pdb = new Rfc2898DeriveBytes("12345", iv);
var aes = new AesManaged();
aes.Key = pdb.GetBytes(aes.KeySize / 8);
aes.IV = pdb.GetBytes(aes.BlockSize / 8);
var buffer = new byte[4096];
using (var instream=File.OpenRead("z:/in.txt"))
{
using (var crptoStream=new CryptoStream(instream,
aes.CreateEncryptor(), CryptoStreamMode.Read))
{
using (var outstream = File.OpenWrite("z:/out.bin"))
{
do
{
var count = crptoStream.Read(buffer, 0, buffer.Length);
if(count==0)break;
outstream.Write(buffer, 0, count);
} while (true);
}
}
}
为了检查,我拿了一个 15 字节的文件——预期的输出是 16 字节。添加了一个字节。16 个字节输入 - 32 个输出。
为什么会这样?有足够的数据和 Padding,理论上应该不会干扰。
PKCS#7 对齐在RFC5652中描述。
公式
k - (l mod k)
(其中 l 是输入数据的长度,k 是块的大小)在输入数据是 16 的倍数的情况下将等于 16,即另外 16 个字节将被写入明文text 等于 16。因此,对齐将如下所示:重要提示:当且仅当 k 小于 256 时,此填充方法才有效。
以及计算最终尺寸的公式:
因为您使用的是标准
Padding
- PKCS7。至少 1 个字节用于存储添加的字节数。