如何在两种公钥格式之间转换,一个是“BEGIN RSA PUBLIC KEY”,另一个是“BEGIN PUBLIC KEY”

如何在两种公钥格式之间转换,一种格式是:

-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY----- 

另一种格式是:

 -----BEGIN RSA PUBLIC KEY----- ... -----END RSA PUBLIC KEY----- 

例如我使用ssh-keygen命令生成了id_rsa / id_rsa.pub对,我使用以下命令计算了id_rsa中的公钥:

 openssl rsa -in id_rsa -pubout -out pub2 

然后再次从id_rsa.pub计算公钥使用:

 ssh-keygen -f id_rsa.pub -e -m pem > pub1 

内容是pub1是:

 -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB -----END RSA PUBLIC KEY----- 

pub2的内容是:

 -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS +rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26 ZQIDAQAB -----END PUBLIC KEY----- 

根据我的理解,pub1和pub2包含相同的公钥信息,但它们格式不同,我不知道如何在两种格式之间转换? 任何人都可以给我一些简单的介绍两种格式?

使用phpseclib,一个纯粹的PHP RSA实现 …

 <?php include('Crypt/RSA.php'); $rsa = new Crypt_RSA(); $rsa->loadKey('-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS +rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26 ZQIDAQAB -----END PUBLIC KEY-----'); $rsa->setPublicKey(); echo $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW); 

尽pipe标题是BEGIN PUBLIC KEY,而不是BEGIN RSA PUBLIC KEY,但base64编码的内容似乎是匹配的。 所以也许只是使用str_replace来解决这个问题,你应该很好去!

我想帮助解释这里发生了什么。

RSA “公钥”由两个数字组成:

  • 模数(例如2048位数)
  • 指数(通常65,537)

以你的RSA公钥为例,这两个数字是:

  • 模量 :297,056,429,939,040,947,991,047,334,197,581,225,628,107,021,573,849,359,042,679,698,093,131,908, 015,712,695,688,944,173,317,630,555,849,768,647,118,986,535,684,992,447,654,339,728,777,985,990,170, 679,511,111,819,558,063,246,667,855,023,730,127,805,401,069,042,322,764,200,545,883,378,826,983,730, 553,730,138,478,384,327,116,513,143,842,816,383,440,639,376,515,039,682,874,046,227,217,032,079,079,790,098,143,158,087,443,017,552,531,393,264,852,461,292,775,129,262,080,851,633,535,934,010,704,122,673,027,067,442,627,059,982,393,297,716,922,243,940,155,855,127,430,302,323,883,824,137,412,883,916,794,359,982,603,439,112,095,116,831,297,809,626,059,569,444,750,808,699,678,211,904,501,083,183,234,323,797,142,810,155,862,553,705,570,600,021,649,944,369,726,123,996,534,870,137,000,784,980,673,984,909,570,977,377,882,585,701
  • 指数 :65,537

那么问题就变成了如何将这些数字存储在计算机中。 首先,我们将两者都转换为hex:

  • 模数 :EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • 指数 :010001

RSA发明了第一种格式

RSA首先发明了一种格式:

 RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER -- e } 

他们select使用ASN.1二进制编码标准的DER风格来表示这两个数字[1] :

 SEQUENCE (2 elements) INTEGER (2048 bit): INTEGER (12 bit): 010001 

ASN.1中的最终二进制编码是:

 30 82 01 0A ;sequence (0x10A bytes long) 02 82 01 01 ;integer (0x101 bytes long) 00 EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65 02 03 ;integer (3 bytes long) 010001 

如果您将所有这些字节一起运行,并使用Base64对其进行编码,则会得到:

 MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB 

然后RSA实验室说添加一个标题和预告片:

 -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB -----END RSA PUBLIC KEY----- 

五个连字符,以及单词BEGIN RSA PUBLIC KEY 。 这是您的PEM DER ASN.1 PKCS#1 RSA公钥

  • PEM: base64的同义词
  • DER:ASN.1编码的一种风味
  • ASN.1:使用的二进制编码scheme
  • PKCS#1:规定将公共密钥表示为由模数和指数组成的结构的正式规范
  • RSA公钥:正在使用的公钥algorithm

不只是RSA

在此之后,其他forms的公钥密码学出现了:

  • 的Diffie-Hellman
  • 椭圆曲线

当需要为如何表示这些encryptionalgorithm的参数创build标准时,人们采用了很多与RSA最初定义的相同的想法:

  • 使用ASN.1二进制编码
  • base64它
  • 用五个连字符包起来
  • BEGIN PUBLIC KEY字样

但是,而不是使用:

  • -----BEGIN RSA PUBLIC KEY-----
  • -----BEGIN DH PUBLIC KEY-----
  • -----BEGIN EC PUBLIC KEY-----

他们决定包括将要遵循的对象标识符(OID)。 在RSA公钥的情况下,即:

  • RSA PKCS#11.2.840.113549.1.1.1

这给你一个ASN.1的:

 SEQUENCE (2 elements) SEQUENCE (2 elements) OBJECT IDENTIFIER 1.2.840.113549.1.1.1 NULL BIT STRING (1 element) SEQUENCE (2 elements) INTEGER (2048 bit): INTEGER (12 bit): 010001 

ASN.1中的最终二进制编码是:

 30 82 01 22 ;SEQUENCE (0x122 bytes = 290 bytes) | 30 0D ;SEQUENCE (0x0d bytes = 13 bytes) | | 06 09 ;OBJECT IDENTIFIER (0x09 = 9 bytes) | | 2A 86 48 86 | | F7 0D 01 01 01 ;hex encoding of 1.2.840.113549.1.1 | | 05 00 ;NULL (0 bytes) | 03 82 01 0F 00 ;BIT STRING (0x10f = 271 bytes) | | 30 82 01 0A ;SEQUENCE (0x10a = 266 bytes) | | | 02 82 01 01 ;INTEGER (0x101 = 257 bytes) | | | | 00 ;leading zero of INTEGER | | | | EB 50 63 99 F5 C6 12 F5 A6 7A 09 C1 19 2B 92 FA | | | | B5 3D B2 85 20 D8 59 CE 0E F6 B7 D8 3D 40 AA 1C | | | | 1D CE 2C 07 20 D1 5A 0F 53 15 95 CA D8 1B A5 D1 | | | | 29 F9 1C C6 76 97 19 F1 43 58 72 C4 BC D0 52 11 | | | | 50 A0 26 3B 47 00 66 48 9B 91 8B FC A0 3C E8 A0 | | | | E9 FC 2C 03 14 C4 B0 96 EA 30 71 7C 03 C2 8C A2 | | | | 9E 67 8E 63 D7 8A CA 1E 9A 63 BD B1 26 1E E7 A0 | | | | B0 41 AB 53 74 6D 68 B5 7B 68 BE F3 7B 71 38 28 | | | | 38 C9 5D A8 55 78 41 A3 CA 58 10 9F 0B 4F 77 A5 | | | | E9 29 B1 A2 5D C2 D6 81 4C 55 DC 0F 81 CD 2F 4E | | | | 5D B9 5E E7 0C 70 6F C0 2C 4F CA 35 8E A9 A8 2D | | | | 80 43 A4 76 11 19 55 80 F8 94 58 E3 DA B5 59 2D | | | | EF E0 6C DE 1E 51 6A 6C 61 ED 78 C1 39 77 AE 96 | | | | 60 A9 19 2C A7 5C D7 29 67 FD 3A FA FA 1F 1A 2F | | | | F6 32 5A 50 64 D8 47 02 8F 1E 6B 23 29 E8 57 2F | | | | 36 E7 08 A5 49 DD A3 55 FC 74 A3 2F DD 8D BA 65 | | | 02 03 ;INTEGER (03 = 3 bytes) | | | | 010001 

和以前一样,你把所有这些字节,Base64编码,最后你的第二个例子:

 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS +rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26 ZQIDAQAB 

添加略有不同的标题和预告片,你会得到:

 -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS +rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26 ZQIDAQAB -----END PUBLIC KEY----- 

这是你的X.509 SubjectPublicKeyInfo / OpenSSL PEM公钥 [2] 。

做对,或者破解它

既然您知道编码不是魔术,那么您可以编写parsingRSA模数和指数所需的所有片段。 或者您可以认识到,前24个字节只是在原来的PKCS#1标准之上添加了新的东西

 30 82 01 22 ;SEQUENCE (0x122 bytes = 290 bytes) | 30 0D ;SEQUENCE (0x0d bytes = 13 bytes) | | 06 09 ;OBJECT IDENTIFIER (0x09 = 9 bytes) | | 2A 86 48 86 | | F7 0D 01 01 01 ;hex encoding of 1.2.840.113549.1.1 | | 05 00 ;NULL (0 bytes) | 03 82 01 0F 00 ;BIT STRING (0x10f = 271 bytes) | | ... 

而由于运气和祝福的非凡巧合:

24字节正好对应于32个base64编码字符

这意味着如果你把你的第二个X.509公钥,并分开前32个字符:

 -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB -----END PUBLIC KEY----- 

删除前32个字符,并将其更改为BEGIN RSA PUBLIC KEY

 -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB -----END RSA PUBLIC KEY----- 

你确切地想要什么。

我发现这个网站是一个很好的技术解释不同的格式: https : //polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

“BEGIN RSA PUBLIC KEY”是PKCS#1,它只能包含RSA密钥。

“BEGIN PUBLIC KEY”是PKCS#8,它可以包含多种格式。

如果你只是想用命令行来转换它们,“openssl rsa”对此很有帮助。

从PKCS#8转换为PKCS#1:

 openssl rsa -pubin -in <filename> -RSAPublicKey_out 

从PKCS#1转换为PKCS#8:

 openssl rsa -RSAPublicKey_in -in <filename> -pubout 

除了页眉/页脚之外,pub1和pub2之间的唯一区别是pub2中的这个附加string: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 。 如果删除它,则Base 64与pub1中的相同。

额外的string对应于本答案的algorithm标识符。

虽然以上关于32字节头文件,OID格式等的评论很有意思,但是我个人看不到相同的行为,假设我明白了这一点。 我认为这可能是有益的,进一步探讨这一点,大多数人可能认为是过分的细节。 没有什么比这更多。

首先,我创build了一个RSA私钥,并对其进行了检查:

 >openssl rsa -in newclient_privatekey.pem -check RSA key ok writing RSA key -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4pOYWo+GeAEmU4N1HPZj1dxv70 4hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyozC/zSqcuU6iBrvzDTpyG1zhIG 76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknmLBrtZkLkBhchgYnMswIDAQAB AoGAQaJ5aivspeEXcpahWavzAFLv27+Tz48usUV+stY6arRhqbBEkV19/N5t8EPA 01U6IGDQ8QIXEIW/rtsHKM6DAZhAbakPDJhJRatcMzJ08ryIkP/c3+onkTquiveG brw7xzn6Xa8ls04aQ6VQR4jxXUjV5bB72pFZnGRoAmS2NiECQQDUoISbmTGjnHM+ kEfunNTXbNmKklwTYhyZaSVsSptnD7CvLWB4qB/g4h2/HjsELag6Z7SlWuYr7tba H3nBYn35AkEAykFRudMqlBy3XmcGIpjxOD+7huyViPoUpy3ui/Bj3GbqsbEAt9cR PyOJa1VFa2JqShta1Tdep8LJv1QvgvY7CwJBAML+al5gAXvwEGhB3RXg0fi2JFLG opZMFbpDCUTkrtu3MeuVC7HbTVDpTSpmSO0uCed2D97NG+USZgsnbnuBHdECQQCw S3FWPXdetQ0srzaMz61rLzphaDULuZhpBMNqnTYeNmMaUcPjewagd3Rf52rkKFun juKE+Yd7SXGbYWEskT5zAkAD7tbNwe5ryD2CT71jrY/5uXMR2yg/A4Ry2ocZkQUp iGflLrHnODvHO5LYLBlSKpjanBceYHJLuMFNZruf7uBM -----END RSA PRIVATE KEY----- 

(哦,恐怖!我已经暴露了一个私钥,呃…)

我提取并显示其公钥:

 >openssl rsa -in newclient_privatekey.pem -pubout writing RSA key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm LBrtZkLkBhchgYnMswIDAQAB -----END PUBLIC KEY----- 

恰巧还有另一个公钥输出参数(如前面的评论中提到的那样)。 我使用该关键字提取并显示公钥:

 >openssl rsa -in newclient_privatekey.pem -RSAPublicKey_out writing RSA key -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR 5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE= -----END RSA PUBLIC KEY----- 

好吧。 这两个公钥的值是不一样的,尽pipe它们是从相同的私钥生成的。 还是他们是一样的? 我将两个公钥string剪切并粘贴到它们自己的文件中,然后对它们进行模数检查:

 >openssl rsa -in newclient_publickey.pem -pubin -modulus Modulus= A7FCE94593BBCB450E9D06235092F8E7 866E293985A8F867801265383751CF66 3D5DC6FEF4E219BCD1E61CEE1D76C5CE E855C0CB05D1C1C8600606941FA6381D 3F2A330BFCD2A9CB94EA206BBF30D3A7 21B5CE1206EFA2AB72375B5FA3E52803 CEF6BFDD0919948A316156852563ACB0 1A49E62C1AED6642E40617218189CCB3 writing RSA key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm LBrtZkLkBhchgYnMswIDAQAB -----END PUBLIC KEY----- 

'pubin'告诉rsa这真的应该是一个公钥,不要抱怨它不是私钥。

现在我们拿RSA公钥,显示模数,并将其转换成一个普通的旧公钥(再次,我们必须告诉它input是一个公钥):

 >openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -modulus Modulus= A7FCE94593BBCB450E9D06235092F8E7 866E293985A8F867801265383751CF66 3D5DC6FEF4E219BCD1E61CEE1D76C5CE E855C0CB05D1C1C8600606941FA6381D 3F2A330BFCD2A9CB94EA206BBF30D3A7 21B5CE1206EFA2AB72375B5FA3E52803 CEF6BFDD0919948A316156852563ACB0 1A49E62C1AED6642E40617218189CCB3 writing RSA key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm LBrtZkLkBhchgYnMswIDAQAB -----END PUBLIC KEY----- 

显示相同的模数,并显示相同的“公钥”值。 为了使事情变得更有趣(无论如何),当我们使用RSAPublicKey_out关键字时,我们得到:

 >openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -modulus -RSAPublicKey_out Modulus= A7FCE94593BBCB450E9D06235092F8E7 866E293985A8F867801265383751CF66 3D5DC6FEF4E219BCD1E61CEE1D76C5CE E855C0CB05D1C1C8600606941FA6381D 3F2A330BFCD2A9CB94EA206BBF30D3A7 21B5CE1206EFA2AB72375B5FA3E52803 CEF6BFDD0919948A316156852563ACB0 1A49E62C1AED6642E40617218189CCB3 writing RSA key -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR 5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE= -----END RSA PUBLIC KEY----- 

…当我们将简单的旧“公钥”转换成RSA公钥时:

 >openssl rsa -in newclient_publickey.pem -pubin -RSAPublicKey_out writing RSA key -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR 5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE= -----END RSA PUBLIC KEY----- 

尽pipe我们刚才做了一些这样的命令,但是为了说明问题,我们把它翻转过来,所以从RSA到旧式的“公钥”:

 >openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -pubout writing RSA key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm LBrtZkLkBhchgYnMswIDAQAB -----END PUBLIC KEY----- 

…我们马上回到我们开始的地方。 我们学到了什么?

总结:内部密钥是一样的,只是看起来不一样。 较早的评论指出RSA密钥格式是在PKCS#1中定义的,普通的旧的“公钥”格式是在PKCS#8中定义的。 但是,编辑一个表格并不会把它转换成另一个表格。 希望我现在已经把这个区别打死了。

如果还剩下一点生命的火花,那么让我们更多地讨论这个问题,并且引用最初由RSA私钥生成的证书,检查它的公钥和模数:

 >openssl x509 -in newclient_cert.pem -pubkey -noout -modulus -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm LBrtZkLkBhchgYnMswIDAQAB -----END PUBLIC KEY----- Modulus= A7FCE94593BBCB450E9D06235092F8E7 866E293985A8F867801265383751CF66 3D5DC6FEF4E219BCD1E61CEE1D76C5CE E855C0CB05D1C1C8600606941FA6381D 3F2A330BFCD2A9CB94EA206BBF30D3A7 21B5CE1206EFA2AB72375B5FA3E52803 CEF6BFDD0919948A316156852563ACB0 1A49E62C1AED6642E40617218189CCB3 

…他们都过着幸福的生活:证书具有与RSA公钥,RSA私钥和普通旧“公钥”相同的模数值。 证书包含与我们前面看到的相同的普通旧“公钥”值,尽pipe它使用标记为RSA私钥的文件进行签名。 有一个共识是可以肯定的。

在OpenSSL星系的X509象限中没有“RSAPublicKey_out”等效关键字,所以我们不能尝试,虽然模数值被描述为“RSA密钥模数”,我们认为这个数值是接近的。

我不知道这将如何与DSA签署的证书看起来。

我意识到这并不回答原来的问题,但也许它提供了一些有用的背景。 如果没有,我的道歉。 至less,不要做和不做的事情。

毫无疑问,人们已经注意到“写RSA密钥”稍微有点刺激的重复,当它没有做这样的事情。 我假定rsa模块将普通的旧公钥视为一个真正的RSA密钥,这就是为什么它继续在“RSA密钥”(再加上它是rsa模块,毕竟)上。 如果我正确地记得,通用EVP_PKEY结构对于所有的键types都有一个联合,每个键types都有自己特殊的一组值(有用的g,w,q和其他辅音)。

最后,我注意到有关编程和开发的投诉; 现在,每个OpenSSL命令显然都有相应的代码,如果想要探索今天所有的OpenSSL编程奇迹,命令行似乎是一个合理的开始。 在这个特殊的情况下(正如我目前使用的是最近的cygwin),可能会先检查\ openssl-1.0.2f \ apps \ rsa.c和(对macros有很高的容忍度)\ openssl-1.0。 2F \encryption\ PEM \ pem_all.c