bash 如何将原始模数和指数转换为 RSA 公钥(.pem 格式)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27568570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to convert raw modulus & exponent to RSA public key (.pem format)
提问by Erik Nyquist
I have the modulus & exponent of an RSA public key embedded into a binary file, and I am trying to extract the entire blob and create a usable .pem public key.
我将 RSA 公钥的模数和指数嵌入到二进制文件中,我正在尝试提取整个 blob 并创建一个可用的 .pem 公钥。
Currently, I am extracting the full 260 bytes (4 bytes for the exponent, 256 bytes for the modulus) and encoding as base64. I am doing that using the following shell command :
目前,我正在提取完整的 260 个字节(指数为 4 个字节,模数为 256 个字节)并编码为 base64。我正在使用以下 shell 命令执行此操作:
tail -c $((filesize - start_of_key_data)) filename | head -c $size_of_key_data | base64 > outkey
This gives me the following string :
这给了我以下字符串:
<<<<<< modulus & exponent extracted from binary file, base64-encoded >>>>>>
tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4F
vzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+
sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1Lll
RWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/r
ZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=
Now, when I take the key.pem keypair that the modulus & exponent were originally extracted from, and display the public portion like so
现在,当我采用最初从中提取模数和指数的 key.pem 密钥对,并像这样显示公共部分时
openssl rsa -in key.pem -pubout -out pubkey.pem
I get this string (I have omitted the header & footer lines :
我得到这个字符串(我省略了页眉和页脚行:
<<<<<<<<< valid public key data extracted from keypair >>>>>>>>>
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtZyrQA6cZFJfVm6FyXwt
ZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZ
U71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDv
YDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGy
a9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx4
1YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/
ZwIDAQAB
You can see that the key data which I have extracted and base64-encoded myself is actually present in the data of the valid public key data extracted from the key.pem using openssl. However there are 45 characters at the beginning, that my own extracted data does not have -
可以看到,我自己提取并base64编码的密钥数据实际上存在于使用openssl从key.pem中提取的有效公钥数据的数据中。但是开头有 45 个字符,我自己提取的数据没有 -
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
and the last 8 characters also differ.
并且最后 8 个字符也不同。
ZwIDAQAB
Can anybody offer some advice on how to convert a modulus and exponent into a usable public key?
任何人都可以就如何将模数和指数转换为可用的公钥提供一些建议吗?
(the goal is to do this in a bash script, not python or C as I've seen many suggest.)
(目标是在 bash 脚本中执行此操作,而不是像我看到的许多建议的那样使用 python 或 C。)
回答by Konstantin Shemyak
Command which you used, openssl rsa -in key.pem -pubout -out pubkey.pem
, produces the ASN.1 structure like this:
您使用的命令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
(You can see the structure with openssl asn1parse -in pubkey.pem
, or using an online ASN.1 decoder).
(您可以使用openssl asn1parse -in pubkey.pem
或使用在线 ASN.1 解码器查看结构)。
It contents:
它的内容:
- a fixed header (contains all bytes, specifying the encoding of the whole sequence plus the encoding of the modulus)
- modulus
- header, specifying encoding of the exponent
- exponent
- 一个固定的头部(包含所有字节,指定整个序列的编码加上模数的编码)
- 模数
- 标头,指定指数的编码
- 指数
If you have the modulus and exponent bytes correctly collected, you can construct the the public key in form, understandable by OpenSSL, by concatenating these four things. You already have the first longer header. The "middle header" is '02 03':
如果您正确收集了模数和指数字节,则可以通过连接这四个东西来构造 OpenSSL 可以理解的形式的公钥。您已经有了第一个更长的标题。“中间标题”是“02 03”:
- '02' for the integer
- length of the integer itself is 3 bytes (65537 = 01 00 01)
- '02' 表示整数
- 整数本身的长度是 3 个字节 (65537 = 01 00 01)
If your modulus is 2048 bits (256 bytes) and exponent 3 bytes (so that the length fields remain valid), the PEM file can be produced by concatenating these four:
如果您的模数是 2048 位(256 字节)和指数 3 字节(以便长度字段保持有效),则可以通过连接以下四个来生成 PEM 文件:
<header> <modulus> 0x02 0x03 <exponent>
That is why the last bytes from the binary dump differ from the OpenSSL output: the extracted 260 bytes do not contain 02 03
, but instead record 65537 as 00 01 00 01
(not 01 00 01
as in ASN.1 encoding).
这就是二进制转储中的最后一个字节与 OpenSSL 输出不同的原因:提取的 260 个字节不包含02 03
,而是将 65537 记录为00 01 00 01
(01 00 01
与 ASN.1 编码不同)。
To summarize, you can produce the PEM file like this:
总而言之,您可以像这样生成 PEM 文件:
Convert your extracted modulus+exponent back from base64 and extract them (note the 257byte offset to skip the leading zero byte of 65537!):
将您提取的模数+指数从 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
Create the headers:
创建标题:
echo 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA' | base64 -d > header.bin
echo '02 03' | xxd -r -p > mid-header.bin
Concatenate them together:
将它们连接在一起:
cat header.bin modulus.bin mid-header.bin exponent.bin > key.der
Convert to PEM:
转换为 PEM:
openssl pkey -inform der -outform pem -pubin -in key.der -out key.pem
Test that you get the working key - by checking it with ASN.1 decoder, or by
测试您是否获得了工作密钥 - 通过使用 ASN.1 解码器检查它,或通过
openssl asn1parse -in key.pem
openssl asn1parse -in key.pem -strparse 19