如何在 Java 中本地读取 OpenSSH 或 OpenSSL 私钥?
How to read an OpenSSH or OpenSSL private key natively in Java?
我想在 Java 中本地读取 OpenSSL 私钥,而不使用 BouncyCastle。
我为此进行了广泛的搜索,但找不到答案。当您看到像这样的键时:
-----BEGIN EC PRIVATE KEY-----
...base64 here....
-----END EC PRIVATE KEY-----
那是什么格式?它似乎与 OpenSSH 密钥的编码相同(我认为)。它是 而不是 pkcs8
,尽管 OpenSSL 允许您使用带有 -topk8
参数的 pkcs8
命令将其密钥格式转换为 pkcs8
。
我当然不是唯一对这个问题有 运行 的人,但是尽管进行了广泛的搜索,我还是找不到答案。谢谢!
编辑:
None 被建议的重复项谈论使用纯 java 解决方案(没有 openssl)并且没有 Bouncy Castle。除非有人问过这个确切的问题,否则请不要将其标记为重复。
西方开发商很容易忽视亚洲国家的商业运作方式。举个例子,中国有一整套EC曲线,OpenSSL和Bouncycastle是闻所未闻的,用于企业间的商务,所以这两个工具:OpenSSL和Bouncycastle要么是很旧的版本,要么是没有在全部。像 "just use openssl" 这样的回答既没有帮助也没有建设性。
https://www.rfc-editor.org/rfc/rfc5915
- Elliptic Curve Private Key Format
本节给出了 EC 私钥的语法。
在计算上,EC 私钥是一个无符号整数,但对于
表示,EC 私钥信息应具有 ASN.1 类型
ECPrivateKey:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
开始块和结束块之间的 Base64 块是 ASN.1 编码的私钥数据,采用他的回答中描述的 bartonjs 格式。如果没有库从您那里拿走工作,您就必须自己进行加载。如何为 RSA 执行此操作的示例可以例如被发现 here。其他格式可以通过将相应的算法名称传递给 KeyFactory.getInstance(...);
以类似的方式加载。为此,您必须解析开始块中的文本,并从那里的名称映射到用于创建工厂的算法名称(大多数应该与块中提供的相同,但我不确定您在问题中提供的示例中使用的椭圆曲线。
base64 块需要解码为字节数组才能传递给 KeySpec
。
我想在 Java 中本地读取 OpenSSL 私钥,而不使用 BouncyCastle。
我为此进行了广泛的搜索,但找不到答案。当您看到像这样的键时:
-----BEGIN EC PRIVATE KEY-----
...base64 here....
-----END EC PRIVATE KEY-----
那是什么格式?它似乎与 OpenSSH 密钥的编码相同(我认为)。它是 而不是 pkcs8
,尽管 OpenSSL 允许您使用带有 -topk8
参数的 pkcs8
命令将其密钥格式转换为 pkcs8
。
我当然不是唯一对这个问题有 运行 的人,但是尽管进行了广泛的搜索,我还是找不到答案。谢谢!
编辑: None 被建议的重复项谈论使用纯 java 解决方案(没有 openssl)并且没有 Bouncy Castle。除非有人问过这个确切的问题,否则请不要将其标记为重复。
西方开发商很容易忽视亚洲国家的商业运作方式。举个例子,中国有一整套EC曲线,OpenSSL和Bouncycastle是闻所未闻的,用于企业间的商务,所以这两个工具:OpenSSL和Bouncycastle要么是很旧的版本,要么是没有在全部。像 "just use openssl" 这样的回答既没有帮助也没有建设性。
https://www.rfc-editor.org/rfc/rfc5915
- Elliptic Curve Private Key Format
本节给出了 EC 私钥的语法。 在计算上,EC 私钥是一个无符号整数,但对于 表示,EC 私钥信息应具有 ASN.1 类型 ECPrivateKey:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
开始块和结束块之间的 Base64 块是 ASN.1 编码的私钥数据,采用他的回答中描述的 bartonjs 格式。如果没有库从您那里拿走工作,您就必须自己进行加载。如何为 RSA 执行此操作的示例可以例如被发现 here。其他格式可以通过将相应的算法名称传递给 KeyFactory.getInstance(...);
以类似的方式加载。为此,您必须解析开始块中的文本,并从那里的名称映射到用于创建工厂的算法名称(大多数应该与块中提供的相同,但我不确定您在问题中提供的示例中使用的椭圆曲线。
base64 块需要解码为字节数组才能传递给 KeySpec
。