1

我正在尝试实现我过去提出的这个问题Securely Encrypt 64bits w/o per element overhead?

在我进入的即时窗口中TripleDES.Create().LegalBlockSizes.First(),我得到了

{System.Security.Cryptography.KeySizes}
    MaxSize: 64
    MinSize: 64
    SkipSize: 0

64bits/8bits 每字节是 8bytes。long 的长度到底是多少。无论如何,我通过下面的代码运行它并抛出异常。块的长度为 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);
    }
}
4

1 回答 1

2

我相信这是由于填充。.NET Framework 中对称密码的默认填充模式是 PKCS7:

PKCS #7 填充字符串由一个字节序列组成,每个字节等于添加的填充字节的总数。

如果添加一行:

des.Padding = PaddingMode.None;

在其余的加密代码之前,您应该发现该数组现在长度为 8 个字节。当然,这意味着您必须确保任何要加密的明文都能被块长度整除。

而且,您仍然需要传输另外 8 个字节的 IV。IV 不应重复使用,因此与纯文本相比,您的存储/传输大小仍然增加了一倍。


填充

密码块链接 (CBC) 模式是一种流行的块密码操作模式。它需要长度是块大小的倍数(通常为 8 或 16 字节)的消息,因此必须填充消息以使它们达到此长度。一种方法是用 1 位后跟 0 位来填充最后一个块。如果输入恰好填满了整个块,则会添加一个“虚拟块”来容纳填充;否则,输入明文的结尾可能会被误解为填充。

(添加了重点。CBC 是.NET Framework 中密码的默认模式)

于 2012-08-09T06:11:48.210 回答