当前位置: 首页 > 面试题库 >

将X509公钥转换为RSA公钥

曹振
2023-03-14
问题内容

我有以下格式的公钥

-----BEGIN PUBLIC KEY----- xxxxxxxx -----END PUBLIC KEY-----

我需要将其转换为以下格式

-----BEGIN RSA PUBLIC KEY----- xxxxxxxxx -----END RSA PUBLIC KEY-----

基本上,问题是我正在使用用Java编写的第三方库。

  1. 第三方库使用Java类“ RSAPublicKeySpec”从字符串生成RSAPublicKey类型的实例

  2. 我提供给该第三方库的字符串取自以下格式的文件:

-----BEGIN PUBLIC KEY----- xxxxxxxx -----END PUBLIC KEY-----

  1. 仔细研究一下代码之后,我可以看到,如果我使用java类“ X509EncodedKeySpec”来加载此公共密钥,则代码的签名验证部分将可以完美地工作。但是,由于代码是第三方库,因此我无法更改其代码中的类类型。我需要以某种方式确保我提供给库的输入与“ RSAPublicKeySpec”类兼容,以便正确加载公钥。

问题答案:

“ RSA PUBLIC KEY”格式在早期的SSLeay中使用,后来演变为OpenSSL,但我认为它在2000年之前就已过时,对于Java来说还很早,我
认为 在Java拥有 任何 加密货币之前,甚至是受限制的加密货币都可以从Java 导出。美国。简而言之,“ RSA PUBLIC
KEY”格式是PKCS#1的RSA特定格式,而“ PUBLIC
KEY”是X.509通用结构,可处理多种(且可扩展)算法。因此,知道您的Java库的开发人员如何陷入这种奇怪的局限会很有趣。但不管怎么说 …


尽管这种格式已经过时了,但 OpenSSL仍然支持
它。如果您有可用的openssl命令行(可能在另一个将文件/数据复制到该文件的系统上,请执行以下操作):

openssl rsa -in publickey.pem -out rsapublickey.pem -pubin -RSAPublicKey_out

啊! 写完下面的内容后,
如果您在Java中使用BouncyCastle(或在C中使用OpenSSL库),则现在我注意到(更一般)的重复使用Java生成PKCS#1格式的RSA密钥(以及从那里开始的几个链接)。 (上面的OpenSSL命令行选项)。

无论如何,如果您愿意,这是使用 普通Java 进行编码的两种方法的概述:

0)两者都 始于将输入PEM转换为bytes 。阅读“ ----
BEGIN”行,最好检查一下它是否正确;读取(base64的)以下所有行,直到但不包括“ -----
END”行;将base64连接并解码为字节。Java8提供java.util.Base64;
在此之前,您必须摆弄“内部”类,或者添加诸如commons编解码器之类的几种常见(但不是内置)库之一,或者自己编写(这并不难)。现在选择步骤1或步骤2。

1) 解析 这些字节,作为X.509
SubjectPublicKeyInfo的ASN.1
DER编码,如RFC
5280中所示,包括AlgorithmIdentifier。确切地说,跳过外部序列的标签和长度;跳过AlgorithmIdentifier的标签,长度和内容-
或者更好地提取内容,并检查它是否为rsaEncryption和NULL(或可能省略)参数的OID的SEQUENCE;然后跳过 BIT STRING
的标签,长度和第一个字节(未使用的位),并将(剩余的) 内容 作为编码的密钥-这已经是您想要的PKCS#1
RSAPublicKey结构。继续执行步骤3。

2) 使用标准JCE 读取X.509格式
密钥:将字节包装在中X509EncodedKeySpec,将其.generatePublic()提供KeyFactory给RSA
以供使用,然后将结果转换为RSAPublicKey。然后调用.getModulus().getPublicExponent()
得到的数学值,并且编码它们 与所述结构的ASN.1 DER 在PKCS#定义RSAPublicKey 1
RFC3447(在rfc3279 2.2.1用于PKIX
/
X.509)。BigInteger.toByteArray()精确给出ASN.1想要的大尾数带符号的二进制补码形式,因此包括:获取两个.toByteArray()值,为每个值添加tag
= INTEGER(0x02)和长度前缀,然后添加tag = SEQUENCE-composite(0x30 )和连接长度的前缀。然后继续执行步骤3。

3)现在,您具有了构成PKCS#1 RSAPublicKey的字节, 将其转换为PEM :编码为base64;
如有必要,请分成几行(以64个字符为单位),或者为了确保安全起见;并添加“ BEGIN”和“ END”行,除非不需要。



 类似资料:
  • 我有以下公钥(作为示例): 我需要能够将其转换为可以插入ssh known_hosts文件的格式。例如: 谢了!

  • 这是我生成RSA密钥的代码 现在我想转换DER/ASN.1编码字节,也知道使用Java JCE API生成RSA密钥时使用的默认编码格式是什么。

  • 问:是否可以从Java密钥存储读取RSA密钥对可以从公钥捕获公钥主体标识? 我已经生成了一个带有SHA1 2048位密钥的RSA,使用Java密钥工具并将密钥对存储在JKS文件中。我可以从这里使用代码加载密钥:https://stackoverflow.com/a/26711907/1203182但是我得到的是RSAPublicKey,而不是X509证书。RSA公钥没有从公钥中查找主题标识或DN的

  • 我正在Erlang中创建一个应用程序,给定一个RSA私钥,它可以返回RSA公钥和与该priv密钥相关联的x509公钥。 ----只是一个更新---- 在花了一些时间了解x509并阅读了Erlang public_key文档后,我找到了一个解决方案: 如果我可以通过简单地获取模数和publicExponent,从“RSaprivateKey”生成“RSapublicKey”,那么生成这两个键的代码如

  • 我的公共在ssh-rsa是: ssh rsa aaaab3nzac1yc2aaaaaadaqabaababaqclaxt5s/wux04oxbt9r59wcl45omau3m0063lfyja7ovqavr7/2kHtLF/LoCQCXSZMny8RTCGDjoXD7G/tGsyHFDHCI//Y1VDLE06AlDzrlu69DQY91 6gkhghgjh3sf6us5hxlihrbsflf8g

  • 我需要用java生成openssh格式的密钥对。 我使用java中的KeyPairGenerator生成了一个公私密钥对,并将其保存到一个文件中: 但是,如果我尝试使用这个与ssh-keygen我得到一个"失败加载密钥private.key:无效格式" 如何将PKCS#8私钥转换为openssh格式或生成openssh格式的密钥对?