Java 的 public 密钥表示与 RFC 8410 之间存在差异
Discrepancy between Java's public key representation and RFC 8410
RFC 8410 将此列为 Ed25519 public 密钥的示例:MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
用 ASN.1 解码器解码,变成:
30 2A
30 05
06 03 2B6570 // Algorithm Identifier
03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1
正如预期的那样,这符合 RFC 中的 SubjectPublicKeyInfo
定义。
使用 Java 11+ 中的 Sun 加密提供程序我可以使用此代码生成 X25519(不是 Ed25519 - 这是下面算法标识符的区别)public 密钥:
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
。根据规范,这是否有效?它说:
In this document, we define four new OIDs for identifying the different curve/algorithm pairs: the curves being curve25519 and curve448 and the algorithms being ECDH and EdDSA in pure mode.
For all of the OIDs, the parameters MUST be absent.
你引用的那段之后的段落是这样说的:
It is possible to find systems that require the parameters to be
present. This can be due to either a defect in the original 1997
syntax or a programming error where developers never got input where
this was not true. The optimal solution is to fix these systems;
where this is not possible, the problem needs to be restricted to
that subsystem and not propagated to the Internet.
因此,对 Oracle 实施行为的一个合理解释是,他们希望与需要参数的旧系统进行互操作。这是您为防止拥有大量支持合同的大客户大声抱怨 "upgrading to Java 11 broke my infrastructure".
而做的事情
RFC 8410 将此列为 Ed25519 public 密钥的示例:MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
用 ASN.1 解码器解码,变成:
30 2A
30 05
06 03 2B6570 // Algorithm Identifier
03 21 0019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1
正如预期的那样,这符合 RFC 中的 SubjectPublicKeyInfo
定义。
使用 Java 11+ 中的 Sun 加密提供程序我可以使用此代码生成 X25519(不是 Ed25519 - 这是下面算法标识符的区别)public 密钥:
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
。根据规范,这是否有效?它说:
In this document, we define four new OIDs for identifying the different curve/algorithm pairs: the curves being curve25519 and curve448 and the algorithms being ECDH and EdDSA in pure mode.
For all of the OIDs, the parameters MUST be absent.
你引用的那段之后的段落是这样说的:
It is possible to find systems that require the parameters to be present. This can be due to either a defect in the original 1997 syntax or a programming error where developers never got input where this was not true. The optimal solution is to fix these systems; where this is not possible, the problem needs to be restricted to that subsystem and not propagated to the Internet.
因此,对 Oracle 实施行为的一个合理解释是,他们希望与需要参数的旧系统进行互操作。这是您为防止拥有大量支持合同的大客户大声抱怨 "upgrading to Java 11 broke my infrastructure".
而做的事情