Java和x27之间的差异;s公钥表示和RFC 8410

Java和x27之间的差异;s公钥表示和RFC 8410,java,cryptography,public-key-encryption,x509,asn.1,Java,Cryptography,Public Key Encryption,X509,Asn.1,将其作为Ed25519公钥的示例列出:mcowbqydk2vwayeagb9ecwmezf6fqbrbz9w7lshqhhqowtrbdfw4rxaxzue= 使用ASN.1解码器对此进行解码,这将变成: 30 2A 30 05 06 03 2B6570 // Algorithm Identifier 03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1 30 2C 30 07

将其作为Ed25519公钥的示例列出:
mcowbqydk2vwayeagb9ecwmezf6fqbrbz9w7lshqhhqowtrbdfw4rxaxzue=

使用ASN.1解码器对此进行解码,这将变成:

30 2A
  30 05
    06 03 2B6570 // Algorithm Identifier
  03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1
30 2C
  30 07
    06 03 2B656E // Algorithm Identifier
    05 00        // Algorithm Parameters - NULL
  03 21 00E55CA23F70CA080A7411AD5FB873FFEF8879D7328075F74FF3D8C5FFA2D25043
正如预期的那样,这与RFC中的
SubjectPublicKeyInfo
定义相匹配

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

导入java.security.KeyPairGenerator;
导入java.util.Base64;
公共类打印公钥{
公共静态void main(字符串args[])引发异常{
KeyPairGenerator generator=KeyPairGenerator.getInstance(“X25519”);
字节[]encodedPublicKey=generator.generateKeyPair().getPublic().getEncoded();
System.out.println(Base64.getEncoder().encodeToString(encodedPublicKey));
}
}
这将输出如下内容:
mcwwwwydk2vubqadiqdlxki/cMoICnQRrV+4c//viHnXMoB190/z2MX/otJQQw==

使用ASN.1解码器对此进行解码,这将变成:

30 2A
  30 05
    06 03 2B6570 // Algorithm Identifier
  03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1
30 2C
  30 07
    06 03 2B656E // Algorithm Identifier
    05 00        // Algorithm Parameters - NULL
  03 21 00E55CA23F70CA080A7411AD5FB873FFEF8879D7328075F74FF3D8C5FFA2D25043
在对象标识符之后有一个显式的
NULL
。根据规范,这有效吗?它说:

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

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


你引用的那一段后面的一段说:

可以找到需要修改参数的系统 目前这可能是由于最初的1997年版本存在缺陷 语法或编程错误,开发人员从未在其中获得输入 事实并非如此。最佳解决方案是修复这些系统; 如果这是不可能的,则需要将问题限制在 该子系统不会传播到Internet


因此,对Oracle实现行为的合理解释是,他们希望能够与需要参数的旧系统进行互操作。这是一种防止拥有大型支持合同的大客户大声抱怨“升级到Java 11破坏了我的基础设施”的做法。

请注意,由于ASN.1的工作方式,有标记的值,在使用Base64编码表单之前,这并不重要。Java 11也是在本次RFC一个月后发布的,这意味着在RFC之前,Java 11中的每一个决定基本上都是做出的。我想我不应该停止阅读:P,基于这个措辞,尽管我的应用程序“要求”在传输公钥之前删除可选参数?