【问题标题】:Java: Why does a 512-bit RSA KeyPairGenerator return 65 byte keys?Java:为什么 512 位 RSA KeyPairGenerator 返回 65 字节的密钥?
【发布时间】:2010-12-07 00:26:43
【问题描述】:

这可能是一个新手问题。我正在使用 Java 生成密钥对:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(512, random);

KeyPair keyPair = keyGen.genKeyPair();

RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();

现在我一直认为 privateKey.getModulus() 和 privateKey.getPrivateExponent() 构成“私钥”,它们与传递给密钥生成器的密钥大小(512 位)一样大。

但是,privateKey.getPrivateExponent().toByteArray() 有时返回 64 字节(如我所料),有时返回 65 字节数组。

为什么有时是 65 字节?我在这里遗漏了什么吗?

【问题讨论】:

  • 512 = 密钥中的位数。 512 / 8 = 64 字节。不知道为什么你会得到 65 个字节......

标签: java cryptography rsa


【解决方案1】:

这里a little story on RSA 解释说密钥长度并不总是你想的那样,即它是从最高有效位开始计算的。但是,它不应超过 512 位,因为这是密钥的最大长度。这个故事是关于感知到的密钥长度,而不一定是实现中的密钥长度。

getPrivateExponent 返回一个BigIntegergetPrivateExponent().toByteArray() 返回 BigInteger 的二进制补码表示。 BigInteger 已签名。 512 位(64 字节)没有符号。这意味着:如果设置了最高有效位(符号位)使其无符号,则BigInteger 需要填充一个字节以使其符合要求。如果查看字节,您会发现添加的字节始终为零。

【讨论】:

    【解决方案2】:

    getPrivateExponent() 返回一个 BigInteger,toByteArray() 方法返回一个字节数组,它总是包含一个符号位。如果设置了 512 位指数中的最高有效位,BigInteger 将添加一个额外的第 513 位 0 以指定该数字是正数,而不是第 512 位设置为 1 的 511 位负数。对于 513 位,65 个字节是编码所需。

    如果你查看返回的字节数组的内容,如果你得到一个 65 元素的数组,第一个字节总是 0。

    【讨论】:

    • 大声笑,我猜我们在同一页上,你只用了 1 分钟就击败了我 :)
    • 这不仅发生在 Java 中(因为 BigInteger 签名),而且在 ASN.1 DER 格式中也有类似的原因(因为 ASN.1 的 INTEGER 签名)。
    【解决方案3】:

    8 * 64 = 512 ?

    编辑:我的错,没有看到 64 和 65 之间的交易,确实,好问题。

    【讨论】:

    • 是的,正确 :-) 我的意思是:为什么参数(私有 exp、mod)有时是 65 字节?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 2015-02-16
    • 1970-01-01
    • 2014-12-23
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多