【问题标题】:how to convert raw modulus & exponent to RSA public key (.pem format)如何将原始模数和指数转换为 RSA 公钥(.pem 格式)
【发布时间】:2015-02-18 12:55:15
【问题描述】:

我将 RSA 公钥的模数和指数嵌入到二进制文件中,我正在尝试提取整个 blob 并创建一个可用的 .pem 公钥。

目前,我正在提取完整的 260 个字节(4 个字节用于指数,256 个字节用于模数) 并编码为base64。我正在使用以下 shell 命令执行此操作:

tail -c $((filesize - start_of_key_data)) filename | head -c $size_of_key_data | base64 > outkey

这给了我以下字符串:

<<<<<< 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=

现在,当我获取最初从中提取模数和指数的 key.pem 密钥对时,像这样显示公共部分

openssl rsa -in key.pem -pubout -out pubkey.pem

我得到了这个字符串(我省略了页眉和页脚行:

<<<<<<<<< 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

你可以看到我自己提取和base64编码的关键数据是 实际存在于使用 openssl 从 key.pem 中提取的有效公钥数据的数据中。 但是开头有 45 个字符,我自己提取的数据没有 -

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA

而且最后 8 个字符也不同。

ZwIDAQAB

谁能提供一些关于如何将模数和指数转换为可用公钥的建议?

(目标是在 bash 脚本中执行此操作,而不是我看到的许多建议的 python 或 C。)

【问题讨论】:

    标签: bash rsa public-key-encryption


    【解决方案1】:

    您使用的命令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 或使用online ASN.1 decoder 查看结构。

    它的内容:

    1. 一个固定的头(包含所有字节,指定编码的 整个序列加上模数的编码)
    2. 模数
    3. 标头,指定指数的编码
    4. 指数

    如果您正确收集了模数和指数字节,则可以通过将这四件事连接起来,以 OpenSSL 可以理解的形式构造公钥。您已经有了第一个较长的标题。 “中间标题”是'02 03':

    1. '02' 表示整数
    2. 整数本身的长度为3字节(65537 = 01 00 01)

    如果您的模数是 2048 位(256 字节)和指数 3 字节(以便长度字段保持有效),则可以通过连接这四个来生成 PEM 文件:

    <header> <modulus> 0x02 0x03 <exponent>
    

    这就是二进制转储中最后一个字节与 OpenSSL 输出不同的原因:提取的 260 个字节不包含 02 03,而是将 65537 记录为 00 01 00 01(不是 ASN.1 编码中的 01 00 01) .

    总而言之,您可以像这样生成 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
    

    【讨论】:

      【解决方案2】:

      你可以使用python3

      from Crypto.PublicKey import RSA
      e = int('your exponent', 16)
      n = int('your modules', 16)
      # Construct a `RSAobj` with only ( n, e ), thus with only PublicKey
      RSA.construct( ( n, e ) ).publickey().exportKey()
      

      参考I have a RSA public key exponent and modulus. How can I encrypt a string using Python?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-14
        • 2010-11-03
        • 1970-01-01
        • 2013-04-12
        • 2011-04-03
        • 1970-01-01
        相关资源
        最近更新 更多