java - 为什么 Java DES KeyGenerator 生成的 key 大小不正确?

标签 java cryptography jce key-generator

我正在使用 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 仍然会正确设置它们。您可以通过验证结果键中每个字节 bInteger.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/

相关文章:

java - Xerces2-j XML 模式属性/元素声明数据类型

algorithm - 在 AES 规范 (FIPS 197) 中,为什么 InvCipher 与反向密码不同?

c# - 如何在 C# 中使用 SHA256 和 ECDSA 算法创建数字签名

java - 无法将 CryptoPermission 添加到 java.policy 文件

ssl - Cassandra 抛出 SSLFactory.java 警告

Java 不区分大小写的本地化排序

java - 如何使用 Facelets 将动态支持 bean 传递到 JSF 2.0 页面?

java - 如何使用 eToken 在客户端加密数据

java - local_policy.jar 和 US_export_policy.jar 与 Unlimited Strength Vs Default 不同。

java - 将一个枚举复制到另一个java