我正在使用 Java 的 SunJCE 提供程序来生成 7 位 key :
KeyGenerator v = KeyGenerator.getInstance("DES")
Provider p = v.getProvider
assert(p.getClass().getSimpleName() == "SunJCE")
v.init(56)
Key k = v.generateKey()
assert(k.getEncoded().getLength == 7)
当我运行上面的程序时,我得到了错误,表明k
的长度实际上是8(64位)而不是56位,奇怪的是KeyGenerator
初始化为仅生成56位 key ,那么为什么k
的实际长度不正确?
最佳答案
DES key 使用每 7 位 8 位进行编码,其中每个字节的最低有效位用于使位数为奇数。因此,如果前 7 位有 6、4 或 2 位设置为 1,则最低有效位设置为(1)。否则它会被重置/取消设置/保留为零。因此,56 位 DES key 被编码为 64 位/8 字节,用于三重 DES 的 112 位 2 key 被编码为 128 位,而 168 位 DES key 则使用 192 位进行编码。
奇偶校验位可以用作某种检查,以查看 DES key 是否未被更改(尽管这也不是很好)。如今,大多数 DES 实现都会完全忽略奇偶校验位,但 Java KeyGenerator
仍然会正确设置它们。您可以通过验证结果键中每个字节 b
的 Integer.bitCount(b & 0xFF) % 2 == 1
来测试这一点:它应该始终返回 true
.
更现代的对称密码尝试使用完全(伪)随 secret 钥; 256 位 AES 或 HMAC key 仅由随机字节组成。
对于大多数非对称密码来说,情况并非如此;对大多数非对称密码的公钥或私钥进行编码将导致比特数明显多于 key 大小。非对称密码的 key 大小通常是确定 key 强度的参数的大小,例如RSA 模数的大小。
<小时/>注释:
- DES 仅具有 56 位的 key 大小(和强度),并且被视为完全损坏:使用 128 位或更多的 key (如果您注意的话,这也排除了双 key 112 位三重 DES key )和现代密码,例如 AES。
- 你的断言检验了那些应该永远正确的事情,但对我来说毫无意义。如果有什么需要测试的话,那就是用于生成 key 的随机数生成器(不幸的是,这些随机数生成器很难测试)。
- 当测试提供者名称时 - 如果你问我的话,这是一种危险且不可移植的做法 - 那么你至少应该使用
Provider#getName()
(可能还有其他返回有用信息的 getter关于提供者)而不是类名。类名称是一个实现细节,实际上可能会更改 - 即使提供程序名称不会更改。
关于java - 为什么 Java DES KeyGenerator 生成的 key 大小不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52561729/