我很难理解密码学中的密钥长度要求。我目前正在使用我认为是 56 位的 DES……现在,通过将 8 个字符的密码转换为byte[]
我的密码学作品。如果我使用 7 位密码,则不会。
现在,如果我错了,请原谅我,但这是因为 ASCII 字符是 7 位,因此 8 * 7 = 56 位?
这对我来说似乎不正确。如果我想使用密钥,为什么我不能只传递我的密钥的加盐散列,即 MD5 散列?
我确信这很简单,但我无法清楚地了解发生了什么。
我很难理解密码学中的密钥长度要求。我目前正在使用我认为是 56 位的 DES……现在,通过将 8 个字符的密码转换为byte[]
我的密码学作品。如果我使用 7 位密码,则不会。
现在,如果我错了,请原谅我,但这是因为 ASCII 字符是 7 位,因此 8 * 7 = 56 位?
这对我来说似乎不正确。如果我想使用密钥,为什么我不能只传递我的密钥的加盐散列,即 MD5 散列?
我确信这很简单,但我无法清楚地了解发生了什么。
DES 使用 56 位密钥:8 个字节,其中每个字节中的一位是奇偶校验位。
但是,一般而言,建议使用公认的、众所周知的密钥派生算法将文本密码转换为对称密码密钥,而不管算法如何。
PKCS #5 ( RFC 2898 ) 中描述的 PBKDF2 算法是一种广泛使用的密钥派生函数,可以生成任意长度的密钥。PBKDF2 的核心是通过哈希函数将盐和密码结合起来,以生成实际的密钥。哈希会重复多次,因此攻击者尝试其最常见密码“字典”中的每个条目的成本很高且速度很慢。
旧版本 PBKDF1 可以为 DES 加密生成密钥,但不建议将 DES 和 PBKDF1 用于新应用程序。
大多数支持加密的平台都在其 API 中包含 PKCS #5 密钥派生算法。
每种算法都设计为接受一定的密钥长度。密钥被用作算法的一部分,因此,不能随心所欲。
常见的密钥大小是:
一个数字,如1234567
只是一个 4 字节的变量。key 应该是一个字节数组,例如"1234567"
(在 C 中隐式转换为一个)或 `{ '1', '2', '3', '4', '5', '6', '7' }。
如果您希望将加盐密钥的 MD5 哈希传递给 DES,您应该使用一些密钥压缩技术。例如,您可以取前 7 个字节(有点不受欢迎),或对 MD5 散列执行 DES 加密(使用已知的常量密钥),并将除最后一个字节之外的所有字节作为 DES 操作的密钥。
编辑:我在这里谈论的 DES 是按照 NIST 发布的标准的实现。可能是(如上所述),您的特定 API 期望对密钥长度有不同的要求,并从中派生出最终的 7 字节密钥。
密钥的大小必须为 64 位,但仅使用密钥中的 56 位。其他 8 位是奇偶校验位(内部使用)。
ASCII 字符有 8 位大小。
您不应该将密码直接传递给算法。例如使用Rfc2898DeriveBytes类,它也会给你的密码加盐。它适用于任何长度。
看看这里的例子。
编辑: D'Oh - 你的问题不是 C# 或 .Net 标记:/
根据MSDN , DES 支持 64 位的密钥长度。
为了避免这个问题并提高实施的整体安全性,通常我们会将密钥的一些散列变体传递给加密函数,而不是密钥本身。
此外,使用特定于您正在执行的操作且不会更改的值(例如,内部用户 ID)对散列进行“加盐”是一种很好的做法。这向您保证,对于密钥的任何两个实例,所得到的结果都会不同。
一旦你有了你的派生密钥,你就可以根据你的特定加密函数的要求提取它的前 n 位。
DES 需要 64 位密钥。56 位用于数据,8 位用于奇偶校验。每个字节在最后一个索引处包含一个奇偶校验位。该位用于检查可能发生的错误。如果 7 个数据位的总和为偶数,则正确的奇偶校验位为 0,对于奇数,则为 1。
ASCII 字符包含 8 位,如果不需要纠错,可以使用 8 个字符作为密钥。如果需要 EC,请使用 7 个字符并在索引(基于 0) 7、15、23、31、39、47、55、63 处插入奇偶校验位。
来源:维基百科:https ://en.m.wikipedia.org/wiki/Data_Encryption_Standard
“密钥表面上由 64 位组成;但是,算法实际使用了其中的 56 个。八位仅用于检查奇偶性,然后被丢弃。因此有效密钥长度为 56 位。”</p>
“密钥名义上以 8 个字节存储或传输,每个字节都有奇校验。根据 ANSI X3.92-1981(现称为 ANSI INCITS 92-1981)第 3.5 节:
KEY 的每个 8 位字节中的一位可用于密钥生成、分发和存储中的错误检测。第 8、16、...、64 位用于确保每个字节都是奇校验。”</p>