我应该如何创建我的 DES 密钥?为啥 7 个字符的字符串不够用?

Posted

技术标签:

【中文标题】我应该如何创建我的 DES 密钥?为啥 7 个字符的字符串不够用?【英文标题】:How should I create my DES key? Why is an 7-character string not enough?我应该如何创建我的 DES 密钥?为什么 7 个字符的字符串不够用? 【发布时间】:2009-06-08 15:31:43 【问题描述】:

我很难理解密码学中的密钥长度要求。我目前正在使用我认为是 56 位的 DES……现在,通过将 8 个字符的密码转换为 byte[] 我的密码学工作。如果我使用 7 位密码,则不会。

现在,如果我错了,请原谅我,但这是因为 ASCII 字符是 7 位,因此 8 * 7 = 56 位?

这对我来说似乎不正确。如果我想使用密钥,为什么不能只传递我的密钥的加盐哈希,即 MD5 哈希?

我确信这很简单,但我无法清楚地了解发生了什么。

【问题讨论】:

【参考方案1】:

DES 使用 56 位密钥:8 个字节,其中每个字节中的一位是奇偶校验位。

但是,一般而言,建议使用公认的、众所周知的密钥派生算法将文本密码转换为对称密码密钥,而不管算法如何。

PKCS #5 (RFC 2898) 中描述的 PBKDF2 算法是一种广泛使用的密钥派生函数,可以生成任意长度的密钥。 PBKDF2 的核心是通过哈希函数将盐和密码结合起来,以生成实际的密钥。哈希会重复多次,因此攻击者尝试其最常用密码“字典”中的每个条目会很昂贵且速度很慢。

旧版本 PBKDF1 可以生成用于 DES 加密的密钥,但不建议将 DES 和 PBKDF1 用于新应用程序。

大多数支持加密的平台都在其 API 中包含 PKCS #5 密钥派生算法。

【讨论】:

感谢您指出八个字节中的每一个都有一个奇偶校验位(丢弃?)。【参考方案2】:

每个算法都被设计为接受一定的密钥长度。密钥用作算法的一部分,因此不能随心所欲。

常见的密钥大小有:

DES:56 位密钥 AES:128-256bit 密钥(常用值为 128、192 和 256) RSA(非对称加密):1024、2048、4096 位密钥

一个数字,例如1234567,只是一个4字节的变量。 key 应该是一个字节数组,例如"1234567"(在 C 中可以隐式转换为一个)或 ` '1', '2', '3', '4', '5', '6', '7' .

如果您希望将加盐密钥的 MD5 哈希传递给 DES,您应该使用一些密钥压缩技术。例如,您可以取前 7 个字节(有些不受欢迎),或对 MD5 哈希执行 DES 加密(使用已知的常量密钥),并将除最后一个字节之外的所有字节作为 DES 操作的密钥。

edit:我在这里谈论的 DES 是根据 NIST 发布的标准的实现。可能是这样(如上所述),您的特定 API 期望对密钥长度有不同的要求,并从中派生出最终的 7 字节密钥。

【讨论】:

【参考方案3】:

密钥的大小必须为 64 位,但仅使用密钥中的 56 位。其他 8 位是奇偶校验位(内部使用)。 ASCII 字符有 8 位大小。

【讨论】:

有些对,有些错。 US-ASCII 字符只有 7 位。但是感谢您指出 DES 密钥的每个字节都包含一个奇偶校验位。【参考方案4】:

您不应该将密码直接传递给算法。例如使用Rfc2898DeriveBytes 类,它也会给你的密码加盐。它适用于任何长度。

看看here 的例子。

编辑: D'Oh - 你的问题不是 C# 或 .Net 标记的:/

【讨论】:

【参考方案5】:

根据MSDNDES 支持的密钥长度为 64 位。

【讨论】:

【参考方案6】:

为避免此问题并提高实施的整体安全性,通常我们会将密钥的一些散列变体传递给加密函数,而不是密钥本身。

此外,使用特定于您正在执行的操作且不会更改的值(例如,内部用户 ID)对哈希进行“加盐”是一种很好的做法。这向您保证,对于密钥的任何两个实例,所得到的结果都会不同。

一旦你有了你的派生密钥,你就可以根据你的特定加密函数的要求提取它的前 n 位。

【讨论】:

【参考方案7】:

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 位。”

“密钥名义上以 8 个字节存储或传输,每个字节具有奇校验。根据 ANSI X3.92-1981(现称为 ANSI INCITS 92-1981)第 3.5 节:

KEY 的每个 8 位字节中的一位可用于密钥生成、分发和存储中的错误检测。第 8、16、...、64 位用于确保每个字节都是奇校验。”

【讨论】:

以上是关于我应该如何创建我的 DES 密钥?为啥 7 个字符的字符串不够用?的主要内容,如果未能解决你的问题,请参考以下文章

使用清除密钥进行3DES加密

DES加密解密

从java的DES加密类中得出了十六进制密钥为B0 98 9E BC 07 EC 23 13,如何得到最终的8位有效密钥呢?

Golang:如何使用 DES 和 CBC 加密 5 个字符长的纯文本?

使用弱密钥暴力破解 DES

如何使用 DES 实现 CBC-MAC?