简体   繁体   中英

explanation of a rsa key file

I'm making a pure math demonstration about RSA algorithm, so I made a pair of keys with the command:

ssh-keygen -t rsa -C "my_mail@server.com"

so it made the files id_rsa and id_rsa.pub since these files are just for demonstrative porpoise I have no problem showing them, these are

id_rsa

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3WqSN/xKwYb3NcgkLV0FO+KSKTcAQR/LChN6gXfHi8n+DXy9
4Ms4RnXohW2pSFinTs+k0I6VEgiwUYGqO5Ak6S5k6L4DuOG2frQtLkIvapV+LG4W
8jkWXRgsyrtne3iUTjbUa9/iDPN6hsGuCDANLjodu8dxzOXNApX7EyIv+9NpabcF
kt8AUwN8z8mCz52j4fhzOD/0DlfHWj1trqtNkq9dzKyY+4FOpgxTUSmKBxzuYT6m
f8T3E8S9eHPA9GB9ZidauqdOYhP8YYJp9cTHaxZFpmzjBfY0wAajOjN7oLWuoXRD
Ave8pI6WMABLlC4duVym6hFW+SIjlb0SlitF5QIDAQABAoIBAQDWK1+EB+XHjGVT
AGT9/Bwz8NSwSSNV2wrqlCzLTrEV5ix3n1GLPwcQILzpU0mLUTWEZhVmJoTLDNx/
+oxPUP5jDx1Mg3/WNX3w0Rdix2JWFoQVNee8JLwdEGVDNELEi73oaeDO96AQJvM9
pdpQ0SnurQhVunW5XA8RkUFrIIaJbgjCrCajNdh0uilGXj8MZInQoApCsVd0Eax4
/X1iaCndkAnYGsy7s3YQMrZ3iPigbLG4nuYgS8NYDLQpEX9vq9bqbER5wUjfldyp
0nN3mSltvFItkzW6LfYsgRD86KVUwqMq/EjN6xNX1M4pSfRh9BQKcgwLWQwBDkyw
fcOn4zwBAoGBAPIaiMVf2oIV0bEUCdkY+rFGoNHWgkeMBfbxeqfZ7K9sXp7eLUic
Knciqzh/GQ9PM6H6g8PhedLXonFtzShNG+dFW+UX3fFTdfJDgX0MUih+6qDp5QkI
0Ej1K5y7g9pOEVOxbgyHtN0s38Li6oZHGRnbf7tDrnMpZP0LGdZceiNpAoGBAOog
Dq5/Z8HpYTr/C8GT3BsZTKqs1wawKJaZ9NKf/0+vc1lTZ8ZlSG0Dy9HlECfYdIhX
af5n0QG3OR77gh6oYqt9cCokggTrmgxxz7NdcXQezfQr5zVMeqDc2oTCKymrIXru
WLWZrb0134UgRl6lcIx3XGCci1+BlEJUlAjFGcsdAoGALUhtQI2XLzGpkPdwiBy1
9yaAuf7nSz6TdwbfrDmEnaMlZ42i5qve/X2MjPqo00Y7IBbdQmwP/zG5/oFNGDaj
+3PrpkP6jULREskxlRQS4eQrOoHFBxWQ77R7vcsM9G4Zq4/KR6myWJQmHiuXNhpi
RYXatEoKfRvG+dVztbaCWdECgYAYd6sxH013nW003iybWVl6V4WEnLWIFGbZflNw
o5np+PsEDcxdln4gLnJhiB/NGjjrer8wACd+l2hXzY8GpzBQnbZYISKZYwnhXQ+I
vi46JXH+n4v1LP3vy8TmdOhP3XuNPlV0/Q+EI5otbncMMxv1AhBcZF/IZmFZIT+r
PvX4HQKBgQC2AY43HY/TQABe0SpygRwVfyTNgLsVCZNu+BKZ9V3wc4Wviq8CeXSo
eD6M3j8adkVIsz/QRwiau3RavoMfH3I6K04F+a3TtfuCvlbuj4WOJGU1s29iD8DZ
enu/vDfWeNFZIVvhx2e70ahdpy0ZbV7rYogMesAa+0VOQ0ZfK1a0Jw==
-----END RSA PRIVATE KEY-----

id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdapI3/ErBhvc1yCQtXQU74pIpNwBBH8sKE3qBd8eLyf4NfL3gyzhGdeiFbalIWKdOz6TQjpUSCLBRgao7kCTpLmTovgO44bZ+tC0uQi9qlX4sbhbyORZdGCzKu2d7eJRONtRr3+IM83qGwa4IMA0uOh27x3HM5c0ClfsTIi/702lptwWS3wBTA3zPyYLPnaPh+HM4P/QOV8daPW2uq02Sr13MrJj7gU6mDFNRKYoHHO5hPqZ/xPcTxL14c8D0YH1mJ1q6p05iE/xhgmn1xMdrFkWmbOMF9jTABqM6M3ugta6hdEMC97ykjpYwAEuULh25XKbqEVb5IiOVvRKWK0Xl my_mail@server.com

but when I check the information in https://en.wikipedia.org/wiki/RSA_(cryptosystem) i find that the agorithm is: c = m^e mod nm = c^d mod n

where

e is public key
d is private key
n is the common module

My question is in the files which part is e, which is d and which is n?

or

Is there a way to read it from the file and insert it inside a mpz_class from gmp c++ library directlly?

Any of those are enough for me

The -m command line option to ssh-keygen is documented in the man page as follows:

-m key_format : Specify a key format for the -i (import) or -e (export) conversion options. The supported key formats are: “RFC4716” (RFC 4716/SSH2 public or private key), “PKCS8” (PEM PKCS8 public key) or “PEM” (PEM public key). The default conversion format is “RFC4716”.

As the coment by Artjom B. says that the data is some form of ASN.1, let's export to PEM and feed the result to openssl asn1parse :

$ ssh-keygen -m PEM -e -f id_rsa.pub | openssl asn1parse -i
    0:d=0  hl=4 l= 266 cons: SEQUENCE          
    4:d=1  hl=4 l= 257 prim:  INTEGER           :DD6A9237FC4AC186F735C8242D5D053BE292293700411FCB0A137A8177C78BC9FE0D7CBDE0CB384675E8856DA94858A74ECFA4D08E951208B05181AA3B9024E92E64E8BE03B8E1B67EB42D2E422F6A957E2C6E16F239165D182CCABB677B78944E36D46BDFE20CF37A86C1AE08300D2E3A1DBBC771CCE5CD0295FB13222FFBD36969B70592DF0053037CCFC982CF9DA3E1F873383FF40E57C75A3D6DAEAB4D92AF5DCCAC98FB814EA60C5351298A071CEE613EA67FC4F713C4BD7873C0F4607D66275ABAA74E6213FC618269F5C4C76B1645A66CE305F634C006A33A337BA0B5AEA1744302F7BCA48E9630004B942E1DB95CA6EA1156F9222395BD12962B45E5
  265:d=1  hl=2 l=   3 prim:  INTEGER           :010001

This is the common modulus n followed by the public key e , both given in hexadecimal notation. Looking at the private key:

$ openssl asn1parse -i < id_rsa
    0:d=0  hl=4 l=1188 cons: SEQUENCE          
    4:d=1  hl=2 l=   1 prim:  INTEGER           :00
    7:d=1  hl=4 l= 257 prim:  INTEGER           :DD6A9237FC4AC186F735C8242D5D053BE292293700411FCB0A137A8177C78BC9FE0D7CBDE0CB384675E8856DA94858A74ECFA4D08E951208B05181AA3B9024E92E64E8BE03B8E1B67EB42D2E422F6A957E2C6E16F239165D182CCABB677B78944E36D46BDFE20CF37A86C1AE08300D2E3A1DBBC771CCE5CD0295FB13222FFBD36969B70592DF0053037CCFC982CF9DA3E1F873383FF40E57C75A3D6DAEAB4D92AF5DCCAC98FB814EA60C5351298A071CEE613EA67FC4F713C4BD7873C0F4607D66275ABAA74E6213FC618269F5C4C76B1645A66CE305F634C006A33A337BA0B5AEA1744302F7BCA48E9630004B942E1DB95CA6EA1156F9222395BD12962B45E5
  268:d=1  hl=2 l=   3 prim:  INTEGER           :010001
  273:d=1  hl=4 l= 257 prim:  INTEGER           :D62B5F8407E5C78C65530064FDFC1C33F0D4B0492355DB0AEA942CCB4EB115E62C779F518B3F071020BCE953498B5135846615662684CB0CDC7FFA8C4F50FE630F1D4C837FD6357DF0D11762C7625616841535E7BC24BC1D1065433442C48BBDE869E0CEF7A01026F33DA5DA50D129EEAD0855BA75B95C0F1191416B2086896E08C2AC26A335D874BA29465E3F0C6489D0A00A42B1577411AC78FD7D626829DD9009D81ACCBBB3761032B67788F8A06CB1B89EE6204BC3580CB429117F6FABD6EA6C4479C148DF95DCA9D2737799296DBC522D9335BA2DF62C8110FCE8A554C2A32AFC48CDEB1357D4CE2949F461F4140A720C0B590C010E4CB07DC3A7E33C01
  534:d=1  hl=3 l= 129 prim:  INTEGER           :F21A88C55FDA8215D1B11409D918FAB146A0D1D682478C05F6F17AA7D9ECAF6C5E9EDE2D489C2A7722AB387F190F4F33A1FA83C3E179D2D7A2716DCD284D1BE7455BE517DDF15375F243817D0C52287EEAA0E9E50908D048F52B9CBB83DA4E1153B16E0C87B4DD2CDFC2E2EA86471919DB7FBB43AE732964FD0B19D65C7A2369
  666:d=1  hl=3 l= 129 prim:  INTEGER           :EA200EAE7F67C1E9613AFF0BC193DC1B194CAAACD706B0289699F4D29FFF4FAF73595367C665486D03CBD1E51027D874885769FE67D101B7391EFB821EA862AB7D702A248204EB9A0C71CFB35D71741ECDF42BE7354C7AA0DCDA84C22B29AB217AEE58B599ADBD35DF8520465EA5708C775C609C8B5F819442549408C519CB1D
  798:d=1  hl=3 l= 128 prim:  INTEGER           :2D486D408D972F31A990F770881CB5F72680B9FEE74B3E937706DFAC39849DA325678DA2E6ABDEFD7D8C8CFAA8D3463B2016DD426C0FFF31B9FE814D1836A3FB73EBA643FA8D42D112C931951412E1E42B3A81C5071590EFB47BBDCB0CF46E19AB8FCA47A9B25894261E2B97361A624585DAB44A0A7D1BC6F9D573B5B68259D1
  929:d=1  hl=3 l= 128 prim:  INTEGER           :1877AB311F4D779D6D34DE2C9B59597A5785849CB5881466D97E5370A399E9F8FB040DCC5D967E202E7261881FCD1A38EB7ABF3000277E976857CD8F06A730509DB6582122996309E15D0F88BE2E3A2571FE9F8BF52CFDEFCBC4E674E84FDD7B8D3E5574FD0F84239A2D6E770C331BF502105C645FC8666159213FAB3EF5F81D
 1060:d=1  hl=3 l= 129 prim:  INTEGER           :B6018E371D8FD340005ED12A72811C157F24CD80BB1509936EF81299F55DF07385AF8AAF027974A8783E8CDE3F1A764548B33FD047089ABB745ABE831F1F723A2B4E05F9ADD3B5FB82BE56EE8F858E246535B36F620FC0D97A7BBFBC37D678D159215BE1C767BBD1A85DA72D196D5EEB62880C7AC01AFB454E43465F2B56B427

Comparing that with the document Artjom referenced , you can guess that this sequence of 9 integers probably corresponds to version , modulus , publicExponent , privateExponent , prime1 , prime2 , exponent1 , exponent2 , coefficient . You can recognize the values for modulus and publicExponent since they match what you had in the public key. So in order to read the private key, we know that it suffices to parse PEM-like files. You probably could link against libopenssl and use its API to do that for you.

But what's the format of the id_rsa.pub ? If you run the command without -m flag you will get something like

$ ssh-keygen -e -f id_rsa.pub
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "2048-bit RSA, converted by … from OpenSSH"
AAAAB3NzaC1yc2EAAAADAQABAAABAQDdapI3/ErBhvc1yCQtXQU74pIpNwBBH8sKE3qBd8
eLyf4NfL3gyzhGdeiFbalIWKdOz6TQjpUSCLBRgao7kCTpLmTovgO44bZ+tC0uQi9qlX4s
bhbyORZdGCzKu2d7eJRONtRr3+IM83qGwa4IMA0uOh27x3HM5c0ClfsTIi/702lptwWS3w
BTA3zPyYLPnaPh+HM4P/QOV8daPW2uq02Sr13MrJj7gU6mDFNRKYoHHO5hPqZ/xPcTxL14
c8D0YH1mJ1q6p05iE/xhgmn1xMdrFkWmbOMF9jTABqM6M3ugta6hdEMC97ykjpYwAEuULh
25XKbqEVb5IiOVvRKWK0Xl
---- END SSH2 PUBLIC KEY ----

The base64 digits of the main part of that output are exactly those from the id_rsa.pub line, so it must be a slight variant of this “RFC4716” format. Reading RFC 4716 section 3.4 :

3.4. Public Key File Body

The body of a public key file is the base64 encoded ( [RFC2045] ) public key data as specified by [RFC4253], Section 6.6 :

  string certificate or public key format identifier byte[n] key/certificate data 

As with all other lines, each line in the body MUST NOT be longer than 72 8-bit bytes excluding line termination characters.

And that RFC4253 Section 6.6 writes:

The "ssh-rsa" key format has the following specific encoding:

  string "ssh-rsa" mpint e mpint n 

The types string and mpint used here are explained in RFC4251 Section 5 . Essentially, each is a 32 bit number giving the length in bytes, followed by the actual data. If you look closely, you can identify the same integers as in the other representations.

$ cut -d' ' -f2 < id_rsa.pub | base64 -d | hexdump -C
00000000 [00 00 00 07:73 73 68 2d  72 73 61|00 00 00 03:01  |....ssh-rsa.....|
00000010  00 01|00 00 01 01:00 dd  6a 92 37 fc 4a c1 86 f7  |........j.7.J...|
00000020  35 c8 24 2d 5d 05 3b e2  92 29 37 00 41 1f cb 0a  |5.$-].;..)7.A...|
00000030  13 7a 81 77 c7 8b c9 fe  0d 7c bd e0 cb 38 46 75  |.z.w.....|...8Fu|
00000040  e8 85 6d a9 48 58 a7 4e  cf a4 d0 8e 95 12 08 b0  |..m.HX.N........|
00000050  51 81 aa 3b 90 24 e9 2e  64 e8 be 03 b8 e1 b6 7e  |Q..;.$..d......~|
00000060  b4 2d 2e 42 2f 6a 95 7e  2c 6e 16 f2 39 16 5d 18  |.-.B/j.~,n..9.].|
00000070  2c ca bb 67 7b 78 94 4e  36 d4 6b df e2 0c f3 7a  |,..g{x.N6.k....z|
00000080  86 c1 ae 08 30 0d 2e 3a  1d bb c7 71 cc e5 cd 02  |....0..:...q....|
00000090  95 fb 13 22 2f fb d3 69  69 b7 05 92 df 00 53 03  |..."/..ii.....S.|
000000a0  7c cf c9 82 cf 9d a3 e1  f8 73 38 3f f4 0e 57 c7  ||........s8?..W.|
000000b0  5a 3d 6d ae ab 4d 92 af  5d cc ac 98 fb 81 4e a6  |Z=m..M..].....N.|
000000c0  0c 53 51 29 8a 07 1c ee  61 3e a6 7f c4 f7 13 c4  |.SQ)....a>......|
000000d0  bd 78 73 c0 f4 60 7d 66  27 5a ba a7 4e 62 13 fc  |.xs..`}f'Z..Nb..|
000000e0  61 82 69 f5 c4 c7 6b 16  45 a6 6c e3 05 f6 34 c0  |a.i...k.E.l...4.|
000000f0  06 a3 3a 33 7b a0 b5 ae  a1 74 43 02 f7 bc a4 8e  |..:3{....tC.....|
00000100  96 30 00 4b 94 2e 1d b9  5c a6 ea 11 56 f9 22 23  |.0.K....\...V."#|
00000110  95 bd 12 96 2b 45 e5]                             |....+E.|
00000117

I've edited the output to make the data boundaries more visible. Looking at the hex output, you see these three parts:

[7: "ssh-rsa" | 3: e=0x010001 | 0x101=257: n=0x00dd6a…3b45e5]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM