我正在尝试实施我过去问过的这个问题Securely Encrypt 64bits w/o per element overhead?
在即时窗口中,我输入了TripleDES.Create().LegalBlockSizes.First()
并获得了
{System.Security.Cryptography.KeySizes}
MaxSize: 64
MinSize: 64
SkipSize: 0
每字节64位/ 8位是8字节。确切的长度是多长。无论如何,我通过下面的代码运行它并抛出异常。块的长度是16字节。不是我想要的...我会问如何将它改为64位但是结果说最小和最大都是64位所以我为什么得到128位呢?
long enc(long v, byte[] iv)
{
using (var m = new MemoryStream())
{
using (var c = des.CreateEncryptor(des.Key, iv))
using (var s = new CryptoStream(m, c, CryptoStreamMode.Write))
{
var b = BitConverter.GetBytes(v);
s.Write(b, 0, b.Length);
}
m.Flush();
var arr = m.ToArray();
if(arr.Length!=8)
throw new Exception();
return BitConverter.ToInt64(arr, 0);
}
}
答案 0 :(得分:2)
我认为这是由于填充。 .NET Framework中对称密码的默认padding mode是PKCS7:
PKCS#7填充字符串由一系列字节组成,每个字节都等于添加的填充字节总数。
如果添加一行:
des.Padding = PaddingMode.None;
在加密代码的其余部分之前,您应该发现该数组的长度为8个字节。当然,这意味着您必须确保要加密的任何明文完全可以被块长度整除。
而且,你还需要发送另外8个字节的IV。不应该重复使用IV,因此与明文相比,存储/传输的大小仍然增加了一倍。
密码块链接(CBC)模式是一种流行的分组密码操作模式。它需要长度为块大小的倍数的消息(通常为8或16字节),因此必须填充消息以使它们达到此长度。一种方法是用1位后跟零位填充最后一个块。 如果输入恰好填满整个块,则添加“虚拟块”以容纳填充;否则,输入明文的结尾可能被误解为填充。
(强调补充.CBC是.NET Framework中密码的默认mode)