您使用的命令,openssl rsa -in key.pem -pubout -out pubkey.pem
,生成如下所示的 ASN.1 结构:
SEQUENCE(2 elem)
SEQUENCE(2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.1.1
NULL
BIT STRING(1 elem)
SEQUENCE(2 elem)
INTEGER(2048 bit) 229263895356027367204242482830890190076375310244080661230946245232688…
INTEGER 65537
(你可以看到结构openssl asn1parse -in pubkey.pem
,或使用在线 ASN.1 解码器 http://lapo.it/asn1js).
其内容:
- 固定标头(包含所有字节,指定编码
整个序列加上模数的编码)
- modulus
- header,指定指数的编码
- exponent
如果您正确收集了模数和指数字节,则可以通过连接这四件事以 OpenSSL 可以理解的形式构造公钥。您已经有了第一个较长的标题。 “中间标头”是“02 03”:
- '02' 为整数
- 整数本身的长度为 3 个字节 (65537 = 01 00 01)
如果您的模数为 2048 位(256 字节)且指数为 3 字节(以便长度字段保持有效),则可以通过连接这四个来生成 PEM 文件:
<header> <modulus> 0x02 0x03 <exponent>
这就是二进制转储的最后一个字节与 OpenSSL 输出不同的原因:提取的 260 字节不包含02 03
,而是将 65537 记录为00 01 00 01
(not 01 00 01
如 ASN.1 编码)。
总而言之,您可以像这样生成 PEM 文件:
将提取的模数+指数从 base64 转换回并提取它们(注意257字节偏移量以跳过 65537 的前导零字节!):
echo 'tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=' | base64 -d > modulus-exp.bin
dd if=modulus-exp.bin of=modulus.bin bs=1 count=256
dd if=modulus-exp.bin of=exponent.bin bs=1 skip=257 count=3
创建标题:
echo 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA' | base64 -d > header.bin
echo '02 03' | xxd -r -p > mid-header.bin
将它们连接在一起:
cat header.bin modulus.bin mid-header.bin exponent.bin > key.der
转换为 PEM:
openssl pkey -inform der -outform pem -pubin -in key.der -out key.pem
测试您是否获得工作密钥 - 通过使用 ASN.1 解码器检查它,或者通过
openssl asn1parse -in key.pem
openssl asn1parse -in key.pem -strparse 19