OpenSSL public / private key encryption / decryption operations Try it manually using the *** integers n, e, d *** and *** Python3 *** *** pow function *** in the key. (However, the original value is only one)
There are two ways to create an OpenSSL key.
*** ssh-keygen *** command Issue a private key and public key for SSH to be used when operating the remote machine. You can set a passphrase to open the key file.
*** openssl genrsa *** command Issue a private key and public key for SSL used for HTTPS communication with a browser.
You can experiment with encryption / decryption with either key, This time I will experiment with the key for SSL.
The version of OpenSSL used in this experiment is as follows.
$ openssl version
OpenSSL 1.1.1 11 Sep 2018
To generate a private key file for SSH, use the `` `ssh-keygen``` command.
By default, the key pair is created in the `` `~ / .ssh / directory, so To prevent accidentally overwriting an existing file
-f```Use the option to specify the output file name.
Also, in recent OpenSSL, the key format is ** new format (OPENSSH PRIVATE KEY) **, so If you want to output in pem format, add the `` `-m pem``` option.
I will ask for a passphrase on the way, but since this is an experiment, I set it to ** no passphrase **.
$ ssh-keygen -f ./id_isa -m pem
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): <---Enter as it is
Enter same passphrase again: <---Enter as it is
Your identification has been saved in ./id_isa.
Your public key has been saved in ./id_isa.pub.
The key fingerprint is:
SHA256:hV6oIMp511t1OxxtRsutREQ8EUvde96S7uevqj9n8Yc root@67bdd8cc774c
The key's randomart image is:
+---[RSA 2048]----+
| +B=.|
| o o*.=|
| . . o o. ooBo|
|.... ..o o. o.=o.|
|.o . ...S. +.oo|
| . . o = o|
| . . = |
| . E +|
| .oo*o+=|
+----[SHA256]-----+
In this article, the work after generating the public key is explained using the SSL key, so If you want to work with your SSH private key
Replace the private key file key-private.pem
with id_isa
.
openssl genrsa
Generate a private key file with the command.
By default, the key length is 2048 bits.
$ openssl genrsa > key-private.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................+++++
.............+++++
e is 65537 (0x010001)
Let's look at the contents of the key file with the cat command.
By default, key files are BASE64 encoded and stored between fixed header footers called PEM format.
$ cat key-private.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAl+RPByBaEZjV2Lb8Z4VZ29XxNvRKn777wXHxEIIjJArgTXHS
tRO2Yt15omy17YHt0vv0NYjMJoyV1nFaaGEsMdmmpqh4vbZGHNDgPwPe7IfOMujm
UI9AmTtajnlEj/sxKdWlgQ9EVgSIUkTWxpad1DX7/gE2JfnxwgNXxCxkRD8XIcux
ODCVeq53I/ZOOQcixCPYijD3p1X+H33q8AEtPLV1dakeYtg4O5TFsbo2/E7bent4
fVlZxb/pxB+nbv/QM0CP47lBpT1nXYG4o9C3GU48e1riuPGVgVJ7yjVBfIJXlt6s
Xch+MID/iZPiNp7FbQlD1yfOqMLjkNsF+ZWI4wIDAQABAoIBAAoIebPlzi1FZDLJ
e4i3BUWBL0rK/jbpHaYciajmf728vi4/a4SshaqoKIWzGp1SrMv3+pyiqaGOPcOJ
f0hPyuSMFPcDP96AMMdsgLOI5OvI2LUCL1x46fJ1OjkZB49fL1MtGp6YzJHGAN82
Tt2VS12eJ0QS/mmpxe9j2yNJL2JWknpduzrWRluvIUvgtY6LSOHBrCjxsns30NWA
kVES4R8SJihR9xKRWEaj3EX3BLheNrwQTByEEFYxAMlzv9mX1XRyK+KU1vZef11I
MA/bxZLBZ7xx3tjt+/yBSgr8zMDOsrz69cwG98cv5Yw3tjar2OU9AF460GkoiZeO
QsmNJ4kCgYEAxpUaHoCRtdnxXxh7Er/oqBpuqIvNa4oni/tJEArgxty0k8Ul6DoQ
mcu79MhyKm3hOFPDNeZyZLuGeyODe3zTDXVLE8Qc9k1KA4B5V5XknDR0RCRvcxPQ
Q51oME68n+nnHTUvi6Qyg4C7t2YWOzJjuQAKmHNPfoWeJpp9Qm2h3j8CgYEAw881
lrR04Bp4jm9NfpPboVXhEkVcTrxbro9HMqyUtYCDJROtLMjG+kauH/yK5DPlFglE
o4ZGSxFcFk9xk2nxrlLTlI+wi7r5+E7WRUH4yzTdImTmJ92dc5GkAkForgO0+qbk
IH04ytYcKxiYLdL3e00CH2a7W41a3MWlmAidNF0CgYAkivOPgWFO8Zg1Q7ACN0Z9
CMAsS+21SGsWm1tKlHXgomSofLMJFQZRBujDls9Ld4TmdKOLm6iZWNjaeCKN6t57
r4XtUT1zJa3lDxNFRtQW2qA6menYZ2D/0EuH+DVFyCk7eroRHFofUOU6TpLwuckY
FiXc//s08Sm1OOCsBLiwyQKBgQCIVbrrPqRt8SBllAuyCUMP91qpvQ+DZtSzGuGo
387+/QbTBvs5xmX8lr/gV5dhQtzL1hIrhW9mDyU+B3x99nMnPFZDBzUWZU5s3H+G
Y2PWIO2jZ/t0YHKjqBE43NAE8WHOb+tAz89+M0wTmaFDrrNP75N9x6rGGQrd0uP0
knLapQKBgBoxOwQM1LpaFrWvK8HmZHxfp9sRW+UAVFddJ40Eke3sHg8g2KzThigB
2Nfjafs92N2TJqm7xuy1wUMJA6AbYCXwKj0hfOooMleqkQZjdtpw2HUoPKD7UhGw
NIPNEBzPVT3QFfhpEyQDpwF4nBWhGSvyoZxqPdyeo981twpehFX6
-----END RSA PRIVATE KEY-----
-text -noout
optionBy the way, the contents of the key are in the following format.
ITU-T X.690 https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
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
}
You can extract the key file with the following command.
$ openssl rsa -in key-private.pem -text -noout
RSA Private-Key: (2048 bit, 2 primes)
modulus:
00:97:e4:4f:07:20:5a:11:98:d5:d8:b6:fc:67:85:
59:db:d5:f1:36:f4:4a:9f:be:fb:c1:71:f1:10:82:
23:24:0a:e0:4d:71:d2:b5:13:b6:62:dd:79:a2:6c:
b5:ed:81:ed:d2:fb:f4:35:88:cc:26:8c:95:d6:71:
5a:68:61:2c:31:d9:a6:a6:a8:78:bd:b6:46:1c:d0:
e0:3f:03:de:ec:87:ce:32:e8:e6:50:8f:40:99:3b:
5a:8e:79:44:8f:fb:31:29:d5:a5:81:0f:44:56:04:
88:52:44:d6:c6:96:9d:d4:35:fb:fe:01:36:25:f9:
f1:c2:03:57:c4:2c:64:44:3f:17:21:cb:b1:38:30:
95:7a:ae:77:23:f6:4e:39:07:22:c4:23:d8:8a:30:
f7:a7:55:fe:1f:7d:ea:f0:01:2d:3c:b5:75:75:a9:
1e:62:d8:38:3b:94:c5:b1:ba:36:fc:4e:db:7a:7b:
78:7d:59:59:c5:bf:e9:c4:1f:a7:6e:ff:d0:33:40:
8f:e3:b9:41:a5:3d:67:5d:81:b8:a3:d0:b7:19:4e:
3c:7b:5a:e2:b8:f1:95:81:52:7b:ca:35:41:7c:82:
57:96:de:ac:5d:c8:7e:30:80:ff:89:93:e2:36:9e:
c5:6d:09:43:d7:27:ce:a8:c2:e3:90:db:05:f9:95:
88:e3
publicExponent: 65537 (0x10001)
privateExponent:
0a:08:79:b3:e5:ce:2d:45:64:32:c9:7b:88:b7:05:
45:81:2f:4a:ca:fe:36:e9:1d:a6:1c:89:a8:e6:7f:
bd:bc:be:2e:3f:6b:84:ac:85:aa:a8:28:85:b3:1a:
9d:52:ac:cb:f7:fa:9c:a2:a9:a1:8e:3d:c3:89:7f:
48:4f:ca:e4:8c:14:f7:03:3f:de:80:30:c7:6c:80:
b3:88:e4:eb:c8:d8:b5:02:2f:5c:78:e9:f2:75:3a:
39:19:07:8f:5f:2f:53:2d:1a:9e:98:cc:91:c6:00:
df:36:4e:dd:95:4b:5d:9e:27:44:12:fe:69:a9:c5:
ef:63:db:23:49:2f:62:56:92:7a:5d:bb:3a:d6:46:
5b:af:21:4b:e0:b5:8e:8b:48:e1:c1:ac:28:f1:b2:
7b:37:d0:d5:80:91:51:12:e1:1f:12:26:28:51:f7:
12:91:58:46:a3:dc:45:f7:04:b8:5e:36:bc:10:4c:
1c:84:10:56:31:00:c9:73:bf:d9:97:d5:74:72:2b:
e2:94:d6:f6:5e:7f:5d:48:30:0f:db:c5:92:c1:67:
bc:71:de:d8:ed:fb:fc:81:4a:0a:fc:cc:c0:ce:b2:
bc:fa:f5:cc:06:f7:c7:2f:e5:8c:37:b6:36:ab:d8:
e5:3d:00:5e:3a:d0:69:28:89:97:8e:42:c9:8d:27:
89
prime1:
00:c6:95:1a:1e:80:91:b5:d9:f1:5f:18:7b:12:bf:
e8:a8:1a:6e:a8:8b:cd:6b:8a:27:8b:fb:49:10:0a:
e0:c6:dc:b4:93:c5:25:e8:3a:10:99:cb:bb:f4:c8:
72:2a:6d:e1:38:53:c3:35:e6:72:64:bb:86:7b:23:
83:7b:7c:d3:0d:75:4b:13:c4:1c:f6:4d:4a:03:80:
79:57:95:e4:9c:34:74:44:24:6f:73:13:d0:43:9d:
68:30:4e:bc:9f:e9:e7:1d:35:2f:8b:a4:32:83:80:
bb:b7:66:16:3b:32:63:b9:00:0a:98:73:4f:7e:85:
9e:26:9a:7d:42:6d:a1:de:3f
prime2:
00:c3:cf:35:96:b4:74:e0:1a:78:8e:6f:4d:7e:93:
db:a1:55:e1:12:45:5c:4e:bc:5b:ae:8f:47:32:ac:
94:b5:80:83:25:13:ad:2c:c8:c6:fa:46:ae:1f:fc:
8a:e4:33:e5:16:09:44:a3:86:46:4b:11:5c:16:4f:
71:93:69:f1:ae:52:d3:94:8f:b0:8b:ba:f9:f8:4e:
d6:45:41:f8:cb:34:dd:22:64:e6:27:dd:9d:73:91:
a4:02:41:68:ae:03:b4:fa:a6:e4:20:7d:38:ca:d6:
1c:2b:18:98:2d:d2:f7:7b:4d:02:1f:66:bb:5b:8d:
5a:dc:c5:a5:98:08:9d:34:5d
exponent1:
24:8a:f3:8f:81:61:4e:f1:98:35:43:b0:02:37:46:
7d:08:c0:2c:4b:ed:b5:48:6b:16:9b:5b:4a:94:75:
e0:a2:64:a8:7c:b3:09:15:06:51:06:e8:c3:96:cf:
4b:77:84:e6:74:a3:8b:9b:a8:99:58:d8:da:78:22:
8d:ea:de:7b:af:85:ed:51:3d:73:25:ad:e5:0f:13:
45:46:d4:16:da:a0:3a:99:e9:d8:67:60:ff:d0:4b:
87:f8:35:45:c8:29:3b:7a:ba:11:1c:5a:1f:50:e5:
3a:4e:92:f0:b9:c9:18:16:25:dc:ff:fb:34:f1:29:
b5:38:e0:ac:04:b8:b0:c9
exponent2:
00:88:55:ba:eb:3e:a4:6d:f1:20:65:94:0b:b2:09:
43:0f:f7:5a:a9:bd:0f:83:66:d4:b3:1a:e1:a8:df:
ce:fe:fd:06:d3:06:fb:39:c6:65:fc:96:bf:e0:57:
97:61:42:dc:cb:d6:12:2b:85:6f:66:0f:25:3e:07:
7c:7d:f6:73:27:3c:56:43:07:35:16:65:4e:6c:dc:
7f:86:63:63:d6:20:ed:a3:67:fb:74:60:72:a3:a8:
11:38:dc:d0:04:f1:61:ce:6f:eb:40:cf:cf:7e:33:
4c:13:99:a1:43:ae:b3:4f:ef:93:7d:c7:aa:c6:19:
0a:dd:d2:e3:f4:92:72:da:a5
coefficient:
1a:31:3b:04:0c:d4:ba:5a:16:b5:af:2b:c1:e6:64:
7c:5f:a7:db:11:5b:e5:00:54:57:5d:27:8d:04:91:
ed:ec:1e:0f:20:d8:ac:d3:86:28:01:d8:d7:e3:69:
fb:3d:d8:dd:93:26:a9:bb:c6:ec:b5:c1:43:09:03:
a0:1b:60:25:f0:2a:3d:21:7c:ea:28:32:57:aa:91:
06:63:76:da:70:d8:75:28:3c:a0:fb:52:11:b0:34:
83:cd:10:1c:cf:55:3d:d0:15:f8:69:13:24:03:a7:
01:78:9c:15:a1:19:2b:f2:a1:9c:6a:3d:dc:9e:a3:
df:35:b7:0a:5e:84:55:fa
asn1parse
optionopenssl asn1parse
It can also be expanded with a command.
$ openssl asn1parse -in key-private.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 :97E44F07205A1198D5D8B6FC678559DBD5F136F44A9FBEFBC171F1108223240AE04D71D2B513B662DD79A26CB5ED81EDD2FBF43588CC268C95D6715A68612C31D9A6A6A878BDB6461CD0E03F03DEEC87CE32E8E6508F40993B5A8E79448FFB3129D5A5810F445604885244D6C6969DD435FBFE013625F9F1C20357C42C64443F1721CBB13830957AAE7723F64E390722C423D88A30F7A755FE1F7DEAF0012D3CB57575A91E62D8383B94C5B1BA36FC4EDB7A7B787D5959C5BFE9C41FA76EFFD033408FE3B941A53D675D81B8A3D0B7194E3C7B5AE2B8F19581527BCA35417C825796DEAC5DC87E3080FF8993E2369EC56D0943D727CEA8C2E390DB05F99588E3
268:d=1 hl=2 l= 3 prim: INTEGER :010001
273:d=1 hl=4 l= 256 prim: INTEGER :0A0879B3E5CE2D456432C97B88B70545812F4ACAFE36E91DA61C89A8E67FBDBCBE2E3F6B84AC85AAA82885B31A9D52ACCBF7FA9CA2A9A18E3DC3897F484FCAE48C14F7033FDE8030C76C80B388E4EBC8D8B5022F5C78E9F2753A3919078F5F2F532D1A9E98CC91C600DF364EDD954B5D9E274412FE69A9C5EF63DB23492F6256927A5DBB3AD6465BAF214BE0B58E8B48E1C1AC28F1B27B37D0D580915112E11F12262851F712915846A3DC45F704B85E36BC104C1C8410563100C973BFD997D574722BE294D6F65E7F5D48300FDBC592C167BC71DED8EDFBFC814A0AFCCCC0CEB2BCFAF5CC06F7C72FE58C37B636ABD8E53D005E3AD0692889978E42C98D2789
533:d=1 hl=3 l= 129 prim: INTEGER :C6951A1E8091B5D9F15F187B12BFE8A81A6EA88BCD6B8A278BFB49100AE0C6DCB493C525E83A1099CBBBF4C8722A6DE13853C335E67264BB867B23837B7CD30D754B13C41CF64D4A0380795795E49C347444246F7313D0439D68304EBC9FE9E71D352F8BA4328380BBB766163B3263B9000A98734F7E859E269A7D426DA1DE3F
665:d=1 hl=3 l= 129 prim: INTEGER :C3CF3596B474E01A788E6F4D7E93DBA155E112455C4EBC5BAE8F4732AC94B580832513AD2CC8C6FA46AE1FFC8AE433E5160944A386464B115C164F719369F1AE52D3948FB08BBAF9F84ED64541F8CB34DD2264E627DD9D7391A4024168AE03B4FAA6E4207D38CAD61C2B18982DD2F77B4D021F66BB5B8D5ADCC5A598089D345D
797:d=1 hl=3 l= 128 prim: INTEGER :248AF38F81614EF1983543B00237467D08C02C4BEDB5486B169B5B4A9475E0A264A87CB30915065106E8C396CF4B7784E674A38B9BA89958D8DA78228DEADE7BAF85ED513D7325ADE50F134546D416DAA03A99E9D86760FFD04B87F83545C8293B7ABA111C5A1F50E53A4E92F0B9C9181625DCFFFB34F129B538E0AC04B8B0C9
928:d=1 hl=3 l= 129 prim: INTEGER :8855BAEB3EA46DF12065940BB209430FF75AA9BD0F8366D4B31AE1A8DFCEFEFD06D306FB39C665FC96BFE057976142DCCBD6122B856F660F253E077C7DF673273C5643073516654E6CDC7F866363D620EDA367FB746072A3A81138DCD004F161CE6FEB40CFCF7E334C1399A143AEB34FEF937DC7AAC6190ADDD2E3F49272DAA5
1060:d=1 hl=3 l= 128 prim: INTEGER :1A313B040CD4BA5A16B5AF2BC1E6647C5FA7DB115BE50054575D278D0491EDEC1E0F20D8ACD3862801D8D7E369FB3DD8DD9326A9BBC6ECB5C1430903A01B6025F02A3D217CEA283257AA91066376DA70D875283CA0FB5211B03483CD101CCF553DD015F869132403A701789C15A1192BF2A19C6A3DDC9EA3DF35B70A5E8455FA
Next, let's generate a public key file from the private key file. By default, it is output to standard output.
$ openssl rsa -in key-private.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl+RPByBaEZjV2Lb8Z4VZ
29XxNvRKn777wXHxEIIjJArgTXHStRO2Yt15omy17YHt0vv0NYjMJoyV1nFaaGEs
Mdmmpqh4vbZGHNDgPwPe7IfOMujmUI9AmTtajnlEj/sxKdWlgQ9EVgSIUkTWxpad
1DX7/gE2JfnxwgNXxCxkRD8XIcuxODCVeq53I/ZOOQcixCPYijD3p1X+H33q8AEt
PLV1dakeYtg4O5TFsbo2/E7bent4fVlZxb/pxB+nbv/QM0CP47lBpT1nXYG4o9C3
GU48e1riuPGVgVJ7yjVBfIJXlt6sXch+MID/iZPiNp7FbQlD1yfOqMLjkNsF+ZWI
4wIDAQAB
-----END PUBLIC KEY-----
Here, write it to a file called key-public.pem
.
$ openssl rsa -in key-private.pem -pubout > key-public.pem
writing RSA key
Let's check the contents of the public key file with the cat command.
$ cat key-public.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl+RPByBaEZjV2Lb8Z4VZ
29XxNvRKn777wXHxEIIjJArgTXHStRO2Yt15omy17YHt0vv0NYjMJoyV1nFaaGEs
Mdmmpqh4vbZGHNDgPwPe7IfOMujmUI9AmTtajnlEj/sxKdWlgQ9EVgSIUkTWxpad
1DX7/gE2JfnxwgNXxCxkRD8XIcuxODCVeq53I/ZOOQcixCPYijD3p1X+H33q8AEt
PLV1dakeYtg4O5TFsbo2/E7bent4fVlZxb/pxB+nbv/QM0CP47lBpT1nXYG4o9C3
GU48e1riuPGVgVJ7yjVBfIJXlt6sXch+MID/iZPiNp7FbQlD1yfOqMLjkNsF+ZWI
4wIDAQAB
-----END PUBLIC KEY-----
Let's expand the public key file.
If you want to read the public key file
-pubin
You need to add the option of.
$ openssl rsa -in key-public.pem -pubin -text -noout
RSA Public-Key: (2048 bit)
Modulus:
00:97:e4:4f:07:20:5a:11:98:d5:d8:b6:fc:67:85:
59:db:d5:f1:36:f4:4a:9f:be:fb:c1:71:f1:10:82:
23:24:0a:e0:4d:71:d2:b5:13:b6:62:dd:79:a2:6c:
b5:ed:81:ed:d2:fb:f4:35:88:cc:26:8c:95:d6:71:
5a:68:61:2c:31:d9:a6:a6:a8:78:bd:b6:46:1c:d0:
e0:3f:03:de:ec:87:ce:32:e8:e6:50:8f:40:99:3b:
5a:8e:79:44:8f:fb:31:29:d5:a5:81:0f:44:56:04:
88:52:44:d6:c6:96:9d:d4:35:fb:fe:01:36:25:f9:
f1:c2:03:57:c4:2c:64:44:3f:17:21:cb:b1:38:30:
95:7a:ae:77:23:f6:4e:39:07:22:c4:23:d8:8a:30:
f7:a7:55:fe:1f:7d:ea:f0:01:2d:3c:b5:75:75:a9:
1e:62:d8:38:3b:94:c5:b1:ba:36:fc:4e:db:7a:7b:
78:7d:59:59:c5:bf:e9:c4:1f:a7:6e:ff:d0:33:40:
8f:e3:b9:41:a5:3d:67:5d:81:b8:a3:d0:b7:19:4e:
3c:7b:5a:e2:b8:f1:95:81:52:7b:ca:35:41:7c:82:
57:96:de:ac:5d:c8:7e:30:80:ff:89:93:e2:36:9e:
c5:6d:09:43:d7:27:ce:a8:c2:e3:90:db:05:f9:95:
88:e3
Exponent: 65537 (0x10001)
asn1parse
optionAs with the private key file, the contents can be expanded with the openssl asn1parse
command.
$ openssl asn1parse -in key-public.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
As you can see by comparing the private key file created first and the public key file, The public key is the content obtained by extracting the following items (required for encryption processing) from the private key.
modulus INTEGER, -- n
publicExponent INTEGER, -- e
With the RSA public key cryptosystem, you can perform encryption / decryption by following the steps below.
encryption *** Get the remainder by multiplying the original value *** by *** e *** and dividing by *** n ***
Decryption *** Get the remainder by multiplying the encrypted value *** by *** d *** and dividing by *** n ***
Start Python3 and from the output result of openssl asn1parse
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
Load the part corresponding to *** into the *** variables n, e, d ***.
openssl asn1parse
Since the output result of is a hexadecimal number, it is recommended to convert it from a hexadecimal number to a decimal number using the int function.
Copy the part corresponding to *** n, e, d *** of the execution result of openssl asn1parse
between the first argument of the int function
''``` `& Paste
If you specify the radix 16 in the second argument of the int function, you can convert it to a decimal number and substitute it.
*** Variable n ***
$ python
>>> n = int('97E44F07205A1198D5D8B6FC678559DBD5F136F44A9FBEFBC171F1108223240AE04D71D2B513B662DD79A26CB5ED81EDD2FBF43588CC268C95D6715A68612C31D9A6A6A878BDB6461CD0E03F03DEEC87CE32E8E6508F40993B5A8E79448FFB3129D5A5810F445604885244D6C6969DD435FBFE013625F9F1C20357C42C64443F1721CBB13830957AAE7723F64E390722C423D88A30F7A755FE1F7DEAF0012D3CB57575A91E62D8383B94C5B1BA36FC4EDB7A7B787D5959C5BFE9C41FA76EFFD033408FE3B941A53D675D81B8A3D0B7194E3C7B5AE2B8F19581527BCA35417C825796DEAC5DC87E3080FF8993E2369EC56D0943D727CEA8C2E390DB05F99588E3', 16)
>>> print(n)
19174567267106562614863777986013190733311720406517163236419798721057651041741132975692437635046772915985388744151381878391739010943167351904934011584525523379391186697776748275394847710370026168707668355363468298465929010753092617924044792285570698575811523066628303754919477816371556100017714944862167735437948517694796555955615103513053419306742815189247527511947589796524356990034768580398382078215058167355632932286761344674894465569796261922954597156699763620980072965273234707300569241109881200233991616854473630970425663335146366570862840409827825897729557509442076004084186075433324566154623231714988236572899
*** Variable e ***
>>> e = int('010001', 16)
>>> print(e)
65537
*** Variable d ***
>>> d = int('0A0879B3E5CE2D456432C97B88B70545812F4ACAFE36E91DA61C89A8E67FBDBCBE2E3F6B84AC85AAA82885B31A9D52ACCBF7FA9CA2A9A18E3DC3897F484FCAE48C14F7033FDE8030C76C80B388E4EBC8D8B5022F5C78E9F2753A3919078F5F2F532D1A9E98CC91C600DF364EDD954B5D9E274412FE69A9C5EF63DB23492F6256927A5DBB3AD6465BAF214BE0B58E8B48E1C1AC28F1B27B37D0D580915112E11F12262851F712915846A3DC45F704B85E36BC104C1C8410563100C973BFD997D574722BE294D6F65E7F5D48300FDBC592C167BC71DED8EDFBFC814A0AFCCCC0CEB2BCFAF5CC06F7C72FE58C37B636ABD8E53D005E3AD0692889978E42C98D2789', 16)
>>> print(d)
1266562425794655073618647403778798277072591629763535096975163780207494565813164542956994713247745242432530446517712622664416103550253619579725335858361093591549574243781002232085452427456121630290301605358323607489799757198988936676887710847372256193214338211322366403024954139906807854448276362914206083993922215094114776012124366236002371990952894667648628314166422099626061405451672662307764909200435879249013664134531240274310366361076547379589865534234754212903474203891892270277583495216595050906895706003102832662158785980707445928619686610586861592808732191214885213804349178521403558427718487767558413690761
The key length of the key generated this time is *** 2048 bits ***, *** The original value *** can be a value from *** 0 to n -1 ***.
By the way, if you check the number of bits *** of *** n, ...
>>> n > pow(2, 2047)
True
>>> n >= pow(2, 2048)
False
*** pow (2, 2047) <n <pow (2, 2048) ***, so You can see that it is *** 2048 bits ***.
Well then Let's verify the encryption / decryption process using the *** pow function *** of *** Python3 ***.
For the time being, this time Let's calculate the original value *** that you want to encrypt as `` `999```.
>>> res = pow(999, e, n)
>>> print(res)
524543469488385391208649776185973445555945805700279654506952471132860336892462605649791076963494809100528555892416120164939727341582216996729091424255089000208944560774832745667292288852130261583027005786502988808264868095073383064006388838941814953270529661005557859554531440610634597104550314977758677359220270332738891641070581370988599952291373443267991140275169462890173229924742294722790318716574816586808362192527012499142400781383842103405401901384801647925304050154989496544788985011577610320345706511051127648308732239235134144620399441561198248345544962316221521339404384225995267012691211102015063665139
>>> pow(res, d, n)
999L
You can see that the original value *** `999``` has been recovered properly. (The
`Lat the end of
999L``` indicates that it is a long integer type.)
Similarly, let's check the operation when generating a digital signature.
Digital signature generation *** Get the remainder by multiplying the original value *** by *** d *** and dividing by *** n ***
Decryption *** Get the remainder by multiplying the generated value *** by *** e *** and dividing by *** n ***
*** Let's calculate with the original value *** as 999
.
>>> res = pow(999, d, n)
>>> print(res)
12515145548924267994063078729711558694795939305875287590392530985593258425241072795063626446654873213977268021736112937973243180699117087520232129972712575525060239166094963345854149835308367216610630688466177263698932768887974675177666169711382251979967291763464839827987347286973550282470918001633660870333020695268293805924000830179825744511427332152587742208811697351651808682552483986509261284189871882421325531674159049062719085809968237649297132520093239037028418224856849358296300721149131689586359427295787997936203041546874958734266989850986012139160164407381286637028534638454642977487380551476319595646032
>>> pow(res, e, n)
999L
As for this process, you can see that the *** original value *** `` `999``` has been recovered.
By the way, *** integer n *** is the *** product *** of two prime numbers p and q **. Let's see if that is the case.
>>> p = int('C6951A1E8091B5D9F15F187B12BFE8A81A6EA88BCD6B8A278BFB49100AE0C6DCB493C525E83A1099CBBBF4C8722A6DE13853C335E67264BB867B23837B7CD30D754B13C41CF64D4A0380795795E49C347444246F7313D0439D68304EBC9FE9E71D352F8BA4328380BBB766163B3263B9000A98734F7E859E269A7D426DA1DE3F', 16)
>>> q = int('C3CF3596B474E01A788E6F4D7E93DBA155E112455C4EBC5BAE8F4732AC94B580832513AD2CC8C6FA46AE1FFC8AE433E5160944A386464B115C164F719369F1AE52D3948FB08BBAF9F84ED64541F8CB34DD2264E627DD9D7391A4024168AE03B4FAA6E4207D38CAD61C2B18982DD2F77B4D021F66BB5B8D5ADCC5A598089D345D', 16)
>>> n == p*q
True
The result of *** n == pq *** is *** True ***, which confirms that they match.
Once the values of *** p and q *** have been determined, the *** integers e and d *** can also be obtained by the RSA key generation procedure.
Here, the *** integer e *** used in the public key is decided to be 65537
.
Let's find the *** integer d *** to use with the private key.
You can find it with the following program.
Read the *** integers p, q, n, e, d *** in the key, Compare the *** integer d *** used for the private key with the *** integer D *** obtained in the RSA key generation procedure.
Will it be the same value as the contents of the OpenSSL key?
check_rsa.py
# -*- coding: utf-8 -*-
import math
def main():
"""Generate public and private keys"""
p = int('C6951A1E8091B5D9F15F187B12BFE8A81A6EA88BCD6B8A278BFB49100AE0C6DCB493C525E83A1099CBBBF4C8722A6DE13853C335E67264BB867B23837B7CD30D754B13C41CF64D4A0380795795E49C347444246F7313D0439D68304EBC9FE9E71D352F8BA4328380BBB766163B3263B9000A98734F7E859E269A7D426DA1DE3F', 16)
q = int('C3CF3596B474E01A788E6F4D7E93DBA155E112455C4EBC5BAE8F4732AC94B580832513AD2CC8C6FA46AE1FFC8AE433E5160944A386464B115C164F719369F1AE52D3948FB08BBAF9F84ED64541F8CB34DD2264E627DD9D7391A4024168AE03B4FAA6E4207D38CAD61C2B18982DD2F77B4D021F66BB5B8D5ADCC5A598089D345D', 16)
n = int('97E44F07205A1198D5D8B6FC678559DBD5F136F44A9FBEFBC171F1108223240AE04D71D2B513B662DD79A26CB5ED81EDD2FBF43588CC268C95D6715A68612C31D9A6A6A878BDB6461CD0E03F03DEEC87CE32E8E6508F40993B5A8E79448FFB3129D5A5810F445604885244D6C6969DD435FBFE013625F9F1C20357C42C64443F1721CBB13830957AAE7723F64E390722C423D88A30F7A755FE1F7DEAF0012D3CB57575A91E62D8383B94C5B1BA36FC4EDB7A7B787D5959C5BFE9C41FA76EFFD033408FE3B941A53D675D81B8A3D0B7194E3C7B5AE2B8F19581527BCA35417C825796DEAC5DC87E3080FF8993E2369EC56D0943D727CEA8C2E390DB05F99588E3', 16)
e = int('010001', 16)
d = int('0A0879B3E5CE2D456432C97B88B70545812F4ACAFE36E91DA61C89A8E67FBDBCBE2E3F6B84AC85AAA82885B31A9D52ACCBF7FA9CA2A9A18E3DC3897F484FCAE48C14F7033FDE8030C76C80B388E4EBC8D8B5022F5C78E9F2753A3919078F5F2F532D1A9E98CC91C600DF364EDD954B5D9E274412FE69A9C5EF63DB23492F6256927A5DBB3AD6465BAF214BE0B58E8B48E1C1AC28F1B27B37D0D580915112E11F12262851F712915846A3DC45F704B85E36BC104C1C8410563100C973BFD997D574722BE294D6F65E7F5D48300FDBC592C167BC71DED8EDFBFC814A0AFCCCC0CEB2BCFAF5CC06F7C72FE58C37B636ABD8E53D005E3AD0692889978E42C98D2789', 16)
N, E, D = generate_keys(p, q)
print("=========Contents of the private key file=========\n"
"p = {0:d}\n"
"q = {1:d}\n".format(p, q))
print("n = {0:d}\n"
"e = {1:d}\n"
"d = {2:d}\n".format(n, e, d))
print("============Results after recalculation============\n"
"N = {0:d}\n"
"E = {1:d}\n"
"D = {2:d}\n".format(N, E, D))
print("===============Matching result===============\n"
"N == n ... {0}\n"
"E == e ... {1}\n"
"D == d ... {2}\n".format(N == n, E == e, D == d))
def lcm(p, q):
"""
Find the least common multiple.
"""
return (p * q) // math.gcd(p, q)
def generate_keys(p, q):
"""
Given two prime numbers p,Generate private and public keys from q.
"""
#Two prime numbers(p, q)Find the product n of
n = p * q
# p -1 and q-Find the least common multiple of 1
l = lcm(p - 1, q - 1)
#Calculate e to use with public key
e = 65537
#Calculate d to use with the private key
"""
for i in range(2, l):
if (e * i) % l == 1:
d = i
break
"""
i = 0
while True:
if (i * l + 1) % e == 0:
d = (i * l + 1) // e
break
i += 1
return n, e, d
if __name__ == "__main__":
main()
Execution example
$ python check_rsa.py
=========Contents of the private key file=========
p = 139449324511565356428512286642655130426447197939578874016855236487282995700169310495082360928168536394955618866705187654764138082404125008789612792239952674581230902932322078366069854469858391655850571761770094638349538491773793929426364268166770990245822712042189994565115142224465057857624774455540121198143
q = 137502044805647677820319568086104169136913652271646067931934573159461074702750974762623151274192421826325614093474060956956735386243214387904643057658451082445275672767583056935887807520136033044478794151296665419648229990606602712134466116705834716237284897734851993095963492054499376932390803569802525619293
n = 19174567267106562614863777986013190733311720406517163236419798721057651041741132975692437635046772915985388744151381878391739010943167351904934011584525523379391186697776748275394847710370026168707668355363468298465929010753092617924044792285570698575811523066628303754919477816371556100017714944862167735437948517694796555955615103513053419306742815189247527511947589796524356990034768580398382078215058167355632932286761344674894465569796261922954597156699763620980072965273234707300569241109881200233991616854473630970425663335146366570862840409827825897729557509442076004084186075433324566154623231714988236572899
e = 65537
d = 1266562425794655073618647403778798277072591629763535096975163780207494565813164542956994713247745242432530446517712622664416103550253619579725335858361093591549574243781002232085452427456121630290301605358323607489799757198988936676887710847372256193214338211322366403024954139906807854448276362914206083993922215094114776012124366236002371990952894667648628314166422099626061405451672662307764909200435879249013664134531240274310366361076547379589865534234754212903474203891892270277583495216595050906895706003102832662158785980707445928619686610586861592808732191214885213804349178521403558427718487767558413690761
============Results after recalculation============
N = 19174567267106562614863777986013190733311720406517163236419798721057651041741132975692437635046772915985388744151381878391739010943167351904934011584525523379391186697776748275394847710370026168707668355363468298465929010753092617924044792285570698575811523066628303754919477816371556100017714944862167735437948517694796555955615103513053419306742815189247527511947589796524356990034768580398382078215058167355632932286761344674894465569796261922954597156699763620980072965273234707300569241109881200233991616854473630970425663335146366570862840409827825897729557509442076004084186075433324566154623231714988236572899
E = 65537
D = 1266562425794655073618647403778798277072591629763535096975163780207494565813164542956994713247745242432530446517712622664416103550253619579725335858361093591549574243781002232085452427456121630290301605358323607489799757198988936676887710847372256193214338211322366403024954139906807854448276362914206083993922215094114776012124366236002371990952894667648628314166422099626061405451672662307764909200435879249013664134531240274310366361076547379589865534234754212903474203891892270277583495216595050906895706003102832662158785980707445928619686610586861592808732191214885213804349178521403558427718487767558413690761
===============Matching result===============
N == n ... True
E == e ... True
D == d ... True
You can see that not only the *** integers n, e *** but also the *** integer d *** match.
*** If you know the integers p and q ***, not only *** public key (combination of integers e and n) *** *** The private key (a combination of integers d and n) *** can also be restored as many times as you like.
Read the contents of the file and read the above *** [6-2](# 6-2-Encryption and Decryption Verification), [6-3](# 6-3-% E6% 95% B4% E6) % 95% B0d-en-% E3% 81% A8pow% E9% 96% A2% E6% 95% B0% E3% 82% 92% E7% 94% A8% E3% 81% 84% E3% 81% 9F% E9% 9B% BB% E5% AD% 90% E7% BD% B2% E5% 90% 8D% E5% BE% A9% E5% 8F% B7% E3% 81% AE% E5% AE% 9F% E9% If you repeat the process of A8% 93) ***, You can create file-based encryption / digital signature generation / decryption processing.
However, it is difficult to ensure the strength of security if you make your own, so it is not recommended. In addition, OpenSSL also has functions for encryption / digital signature generation / decryption on a file-by-file basis.
If you want to create encryption / decryption / digital signature processing in Python3, the following tools are useful.
https://www.pycryptodome.org/en/latest/
https://github.com/NobuyukiInoue/Example_RSA_by_pycryptodome
By the way, the story goes away from Python, but ... Microsoft .NET (C #) provides classes as standard.
https://docs.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.rsacryptoserviceprovider?view=netframework-4.8
Recommended Posts