使用 openssl 以特定格式创建 RSA 密钥

Posted

技术标签:

【中文标题】使用 openssl 以特定格式创建 RSA 密钥【英文标题】:create RSA key in a specific format using openssl 【发布时间】:2021-01-22 17:33:37 【问题描述】:

我们在大型机中使用 ICSF 创建了一个 RSA 密钥对。以十六进制格式生成的公钥大小为 580 个字符,结构分为

前缀 - 18 个字符(9 个字节) - 3082010A0282010100

公共模数 - 512 字符(256 字节) AA5DA28FEDADE7FEAD8C610E4C16E54FD415FEA173518BD9ADC3C7EB332E86E973B7F6E9BF90F277FD4B6A15E736C566857AA58F8C5415E1F606DBF74FAFCBCAE99A4E77AF7F4958E163E2159C6083826D203AD75685A53AFBC7221CDEF23FA68CE41270A1756AC5814A09713A7EB941CD61055143C37FC7AF1E0E6F1539CEEA49F331A0BEC0453F6B6A47A37F66EDDF5F308AED5E5172CD8768CF43CD024E7988905B0C22CAA888E3162E74E93FC292EB905EA050E2DC503AB92E9FE3C6CDACFCDE0D243A40F7E1578E097D65D7848387D1A33374AF93EEF3906B6CB07E5160BF5927E9B49FA68BE27D86AAFCD81EA12E83194BBD1CDEB5E52EB96DD63D0CA9 P>

指数 - 10 个字符(5 个字节) - 0203010001

SHA1 哈希 - 40 个字符(20 字节) - CDC0B4A4253110D6E4A15DF536257A7B89B4231D

我们必须创建一个 RSA 密钥对,并且公钥必须采用与上述相同的格式。我们使用 openssl 进行了尝试,但创建的公钥格式不同。

    生成密钥对 $openssl genrsa -out priv1.key 2048 提取 pem 格式的公钥 $openssl rsa -in priv1.key -text > priv1.pem 将 base64 pem 转换为十六进制。

这种格式叫什么?使用openssl,我们如何生成rsa密钥对,使公钥为上述格式?

【问题讨论】:

【参考方案1】:

除 SHA1 哈希之外的所有内容都只是一个 ASN.1 编码的 PKCS#1 公钥。如果您有 openssl 1.0.0 或更高版本,您可以按如下方式创建:

crow@mac:~$ openssl genrsa 2048 -out key.pem
crow@mac:~$ openssl rsa -in key.pem -RSAPublicKey_out -outform DER 2> /dev/null | xxd -p > hex.txt
crow@mac:~$ cat hex.txt
3082010a0282010100be4a968090c6f608a4151fcf65dfe842e818a8cf56
33e31ad1a912bfd5c453a89360a71b8d72786fbda131ebc3cc03cc742b5c
cbb1b9621cdee34e8c1c25ca125961dc7c5fd1cb18832402ecfb4b0b1bf7
c1b3dd666c0a789d9d721bfc13d4affb2bab0c0122a695ac3288786cb3f3
1a3d56969dbc164e4ef5f4a0319b175e5de29525a84816bbc837d892b9ba
6e3e462fe7a0ca0820ece4148cc76764c978ae2d41159fc4bb55cff31c53
de55511d825b59e07767ee90d184aa0017e99077c09a9badeab7770a401e
afec27f3abc98d141b50a7e4ba8c1c232af0df4ea83c8377f3ad360c17fd
fe762d4ec4502cc4c0dd81ba1df6fc499b490332f21ab511910203010001
crow@mac:~$ 

请注意,前 9 个字节和后 5 个字节与问题中的“前缀”和“指数”相同。

然后将散列附加到末尾,它只是您刚刚进行十六进制编码的同一个 DER 编码公钥的 SHA1 散列(即获取原始 ASN.1 的散列,而不是十六进制编码的散列)文本文件)例如

crow@mac:~$ openssl rsa -in key.pem -RSAPublicKey_out -outform DER | openssl dgst -sha1 | cut -f 2 -d ' ' >> hex.txt

【讨论】:

| openssl dgst 将在所需的十六进制之前输出文字 (stdin)= ,因此您需要类似 sedcutawk 的内容来删除它。 Q 中的数据显然是“编辑”的,因为没有正常的 RSA 生成将产生 n 具有 80-FF 之外的高位字节,如果这样做,ASN.1 编码将不会有“额外”00;一个 SHA1 哈希将在 987654328@ 结束时只有一万亿分之一。 @dave_thompson_085:你是对的,编辑为通过cut 传递。 @Crowman。谢谢!。我们按照 Windows 机器中的建议进行了尝试。 1. openssl genrsa -out key.pem 2048 2. openssl rsa -in key.pem -pubout -out pub.pem - 记录大小为 392 字节。 3. base 64 到 hex 格式 - 记录大小为 588 字节。 4. 使用powershell & 执行cat hex.txt | openssl dgst -sha1 >> hex1.txt 从十六进制数据中获取哈希值。 5. 仅手动连接十六进制数据末尾的哈希值。现在记录的大小是 628 字节。我们预计最终大小为 580 字节。我们在这里做错了什么。 @phoenix:嗯,您没有按照答案中的说明进行操作,这是最明显的问题。你正在做openssl rsa -in key.pem -pubout,但根据答案,你需要做openssl rsa -in key.pem -RSAPublicKey_out -outform DER,这(故意)给你二进制输出,而不是base64编码的输出。这些差异很重要。 @phoenix:更新了答案以显示如何重新计算您的哈希,现在您已经提供了实际值。

以上是关于使用 openssl 以特定格式创建 RSA 密钥的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL笔记-生成RSA公私密钥以PEM格式到char*中(非保存为文件)

通过 OpenSSL (c++) 以 XML (w3c) 格式保存 RSA 公钥和私钥

为 RSA OpenSSL 设置特定密钥

openssl 怎样生成公钥和密钥 x509格式

将 OpenSSL RSA 密钥与 .Net 一起使用

openssl RSA 内存读取密钥