0%

openssl 密钥生成与解析

使用 openssl 生成解析 rsa 公私钥

RSA 算法

RSA 算法原理(一)
RSA 算法原理(二)

从中可以得出如下信息:

- 公式
公钥 KU n:质数 p 和质数 q 的乘积(p 和 q 必须保密)
e:与 (p-1)×(q-1) 互质
私钥 KR n:同公钥 n
d: \(e^{-1}(mod(p-1)(q-1))\)
加密 \(c=m^emodn\)
解密 \(m=c^dmodn\)

n 和 e 封装成公钥,n 和 d 封装成私钥。公钥和私钥的数据都采用 ASN.1 格式表达

实际应用中,e 常常选择 65537

生成

使用 openssl 来生成公钥、私钥

私钥

$ openssl genrsa -out privkey.pem 2048

公钥

$ openssl rsa -in privkey.pem -pubout -out pubkey.pem

证书

$ openssl req -new -key privkey.pem -out ca.csr

解析

openssl 密钥生成和解析

openssl

openssl 的数据编码规则是基于 ans.1
openssl 有多种形式的密钥,openssl 提供 PEM 和 DER 两种编码方式对这些密钥进行编码,并提供相关指令可以使用户在这两种格式之间进行转换。

DER

DER 就是密钥的二进制表述格式。

PEM

PEM 格式就是对 DER 编码转码为 base64 字符格式。通过 base64 解码可以还原 DER 格式。

PEM 格式

公钥

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}
  • modulus 是 RSA 的合数模 n
  • publicExponent 是 RSA 公开幂 e

命令分析公钥如下

$ cat pubkey.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA04VqFIaa59Aba74p+fuL
La4I1KoZJ+40yeg3QFFagCNpqI+Krf+5qZBNuhWrBRtp0LN9IOftfDr/nC+I+04G
CXMX+4ZrPfkWRWkDZr2RC7WqC+/E2Fgx7DBSWqXx1dPog3q3j1eeO8PL/FGA2q6C
9Yy9PW5a/E/YG4ngMOGCvIc1dR2eJkqz6hBOWZB3+GnrV7VoVZZE2hNP3SXsqGZY
FXRntKhuBc1FWMIwSN9tTWC6EhR550HqZx9jogTVDvwVn5yXSNhJ/K1fg7vkQVRa
NMNuz1EX2VT00XJ1U4qd+q7p4PR1N+vDIAHUMABW8HkM0HKlYS+hl/LnZTvRCUcR
XwIDAQAB
-----END PUBLIC KEY-----
$ openssl rsa -pubin -in pubkey.pem -text -noout
RSA Public-Key: (2048 bit)
Modulus:
    00:d3:85:6a:14:86:9a:e7:d0:1b:6b:be:29:f9:fb:
    ...
Exponent: 65537 (0x10001)
$ openssl asn1parse -i -in pubkey.pem
    0:d=0  hl=4 l= 290 cons: SEQUENCE
    4:d=1  hl=2 l=  13 cons:  SEQUENCE
    6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   17:d=2  hl=2 l=   0 prim:   NULL
   19:d=1  hl=4 l= 271 prim:  BIT STRING

私钥

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}
  • modulus 是 RSA 合数模 n
  • publicExponent 是 RSA 的公开幂 e
  • privateExponent 是 RSA 的私有幂 d
  • prime1 是 n 的素数因子 p
  • prime2 是 n 的素数因子 q
  • exponent1 等于 \(d mod (p−1)\)
  • exponent2 等于 \(d mod (q−1)\)
  • coefficient 是 CRT 系数 \((q–1) mod p\)

分析私钥如下

$ cat privkey.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA04VqFIaa59Aba74p+fuLLa4I1KoZJ+40yeg3QFFagCNpqI+K
...
-----END RSA PRIVATE KEY-----
$ openssl rsa -in privkey.pem -text -noout
RSA Private-Key: (2048 bit, 2 primes)
modulus:
    00:d3:85:6a:14:86:9a:e7:d0:1b:6b:be:29:f9:fb:
    ...
publicExponent: 65537 (0x10001)
privateExponent:
    3f:84:70:b6:79:35:4b:27:53:14:a7:a6:33:4b:36:
    ...
prime1:
    00:f9:d6:97:89:e0:a6:78:e4:c9:f8:70:ed:aa:6c:
    ...
prime2:
    00:d8:bc:e6:2b:25:83:48:98:d6:84:fb:90:ef:f4:
    ...
exponent1:
    00:f7:f8:64:aa:05:9e:55:49:87:a9:1d:b4:d6:bc:
    ...
exponent2:
    46:e7:85:65:18:20:9a:df:65:4e:9b:fe:0e:82:26:
    ...
coefficient:
    2c:be:89:1e:ad:1b:c7:1f:f1:72:1e:ae:6e:a8:c6:
    ...
$ openssl asn1parse -i -in privkey.pem
    0:d=0  hl=4 l=1187 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim:  INTEGER           :00
    7:d=1  hl=4 l= 257 prim:  INTEGER           :D3856A14869AE7D01B6BBE29F9FB8B2DAE08D4AA1927EE34C9E83740515A802369A88F8AADFFB9A9904DBA15AB051B69D0B37D20E7ED7C3AFF9C2F88FB4E06097317FB866B3DF91645690366BD910BB5AA0BEFC4D85831EC30525AA5F1D5D3E8837AB78F579E3BC3CBFC5180DAAE82F58CBD3D6E5AFC4FD81B89E030E182BC8735751D9E264AB3EA104E599077F869EB57B568559644DA134FDD25ECA86658157467B4A86E05CD4558C23048DF6D4D60BA121479E741EA671F63A204D50EFC159F9C9748D849FCAD5F83BBE441545A34C36ECF5117D954F4D17275538A9DFAAEE9E0F47537EBC32001D4300056F0790CD072A5612FA197F2E7653BD10947115F
  268:d=1  hl=2 l=   3 prim:  INTEGER           :010001
  273:d=1  hl=4 l= 256 prim:  INTEGER           :3F8470B679354B275314A7A6334B36202182C559CEF40EB40B6D9029E0442CF6756408B6BC496E975C9DFAA34717E1838508612AE07A9033A74E5F77E2FF2B10EB5EE849152B270169167FCEFA5DF406396A1C3620415BBC714649B24B4CCAB5A7C5D21959564ADC210543F44DB6D9DCA2C6B10BD286B1F35351B3E0F9D72885658C1B59062CDE9F71746BBC51AEAB3BF4A72093D61E186A2D241DFB6EF25F21A0F243A557E03F84BFDB67626B2C9E27E44E7865E50AF5937AA4F316D54D7D53B2666628AAF808E70775998B863D5764312E52FAD7796206312803BF685463F91662669C2D4F2B0D75F8AF5591D010C6B29B314EB3C0E0BC47410C3EBC7CF101
  533:d=1  hl=3 l= 129 prim:  INTEGER           :F9D69789E0A678E4C9F870EDAA6C1C1AA9BEE312C19E6B53129FF4F23D9CBCCCEED5DDCF6311E23A1D58741F47C6F065CF2F7A84D0FB989AD87C37B241C69AC5AA3E3E382DF603B774C6AD5CD4F0AAA40F90CCDDD69A758845213AAA0A67745E22C4FF2C703B9E0A4C6F8A73E0A3A848A20C667C8F226BAFEC8004B92CB6851B
  665:d=1  hl=3 l= 129 prim:  INTEGER           :D8BCE62B25834898D684FB90EFF468BBDE358413EA0FF9420A44F4A05636113DB2AEEAEFFECEFBA11807674612AAD21945C157EC60FB7672FC7DEC402695255AFE2FD2D55566DCAAC6FBE6231B8504765DE073F852772706BB2B7E6A7D0AA84607459F8D9EBF3AC63086B6037F626D667A8CE82EA7C96ABCD721BC4C9CEEDD0D
  797:d=1  hl=3 l= 129 prim:  INTEGER           :F7F864AA059E554987A91DB4D6BCBCDC3DF4677E9B4BF86C188548E21202FA6550FC564E5B9F4971B2E4B344C4C210A28C142CBF9C88CB7B8D392532B9143D53C95843FB10AB281F33396AA243FBA6F2753C9C09E6D1A1AC22290C07EF91A52F35C55F1BA53D96EBD3D7B58CB3BEDBED5361896B41C9C126784ECBE15B1EC157
  929:d=1  hl=3 l= 128 prim:  INTEGER           :46E7856518209ADF654E9BFE0E8226C14F30B2C4D10DE8BD721E9CE8D74B58D8965C22FFE09C56359D66CEA25DF90442C04F40345485EF7A2EA00369F93551C332E4F254585C0E54D0441845E3FAE03AD8FB54F5280552FF20BC59DEFC894003A8DD5E153699D8E07D7F948C106062E9E3ADB5478E1C968EB0D2988777CFAD01
 1060:d=1  hl=3 l= 128 prim:  INTEGER           :2CBE891EAD1BC71FF1721EAE6EA8C6091AD8C117029A9142FC4F82F04BED3855EAC22D77ACC401095AE46D6964A5CAC596513BD71554DAE296614AF352CB198C25F0213C062C93A980DAA351583C5BF354E9A39B9FE0B4EC38FFA3C8324D33062AF21FA73AAFF1CDFE6056150C724F46C689F33D132C2AB4CE6F6B79A5A9AFD8
  • 0 表示节点在整个文件中的偏移长度
  • d=0 表示节点深度
  • hl=3 表示节点头字节长度
  • l=135 表示节点数据字节长度
  • cons 表示该节点为结构节点,表示包含子节点或者子结构数据
  • prim 表示该节点为原始节点,包含数据
  • SEQUENCEOCTET STRING 等都是 ASN.1 中定义的数据类型