【问题标题】:Discrepancy between Java's public key representation and RFC 8410Java 的公钥表示与 RFC 8410 之间的差异
【发布时间】:2020-05-26 02:01:41
【问题描述】:

RFC 8410 将此列为 Ed25519 公钥的示例:MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=

用 ASN.1 解码器解码,变成:

30 2A
  30 05
    06 03 2B6570 // Algorithm Identifier
  03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1

正如预期的那样,这与 RFC 中的 SubjectPublicKeyInfo 定义相匹配。

使用 Java 11+ 中的 Sun 加密提供程序,我可以使用此代码生成 X25519(不是 Ed25519 - 这是下面算法标识符的区别)公钥:

import java.security.KeyPairGenerator;
import java.util.Base64;

public class PrintPublicKey {
    public static void main(String args[]) throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("X25519");
        byte[] encodedPublicKey = generator.generateKeyPair().getPublic().getEncoded();
        System.out.println(Base64.getEncoder().encodeToString(encodedPublicKey));
    }
}

这将输出类似:MCwwBwYDK2VuBQADIQDlXKI/cMoICnQRrV+4c//viHnXMoB190/z2MX/otJQQw==

用 ASN.1 解码器解码,变成:

30 2C
  30 07
    06 03 2B656E // Algorithm Identifier
    05 00        // Algorithm Parameters - NULL
  03 21 00E55CA23F70CA080A7411AD5FB873FFEF8879D7328075F74FF3D8C5FFA2D25043

这在对象标识符之后有一个明确的NULL。根据规范,这是否有效?它说:

在本文档中,我们定义了四个新的 OID,用于识别不同的曲线/算法对:曲线为 curve25519 和 curve448,算法为纯模式下的 ECDH 和 EdDSA。

对于所有 OID,参数必须不存在。

【问题讨论】:

  • 请注意,由于 ASN.1 的工作方式,具有标记值,这并不重要,直到您使用 Base64 编码的表单。

标签: java cryptography public-key-encryption x509 asn.1


【解决方案1】:

你引用的那段之后的段落是这样说的:

可以找到需要参数的系统 展示。这可能是由于原始 1997 中的缺陷 开发人员从未得到输入的语法或编程错误 这不是真的。最佳解决方案是修复这些系统; 如果这是不可能的,则需要将问题限制在 该子系统并没有传播到 Internet。

因此,对 Oracle 实现行为的一个合理解释是,它们希望与需要参数的旧系统互操作。这样做是为了防止拥有大量支持合同的大客户大声抱怨“升级到 Java 11 破坏了我的基础架构”。

【讨论】:

  • Java 11 也是在该 RFC 发布一个月后发布的,这意味着基本上所有关于 Java 11 内容的决定都是在 RFC 之前做出的。
  • 我想我不应该停止阅读:P 基于该措辞,尽管我的应用程序“要求”在传输公钥之前删除可选参数?
猜你喜欢
  • 2012-03-31
  • 2022-10-14
  • 2017-01-27
  • 2021-08-16
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多