PythonでPEM形式のRSA鍵を生成する方法のメモ
適当なパラメータをもとに、PythonでPEM形式のRSA鍵を生成する方法のメモ。
環境
Ubuntu 14.04.3 LTS 64bit版
$ uname -a Linux vm-ubuntu64 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.3 LTS Release: 14.04 Codename: trusty
PEM形式のRSA鍵を生成してみる
PEM形式のRSA鍵を生成するには、PyCryptoライブラリが使える。 pipを使ってPyCryptoをインストールするには次のようにする。
$ sudo pip install pycrypto
適当なパラメータn、e、dからPEM形式の秘密鍵を生成するコードを書くと次のようになる。 なお、n、eのみを与えた場合は公開鍵が生成される。
# generate_pem.py from Crypto.PublicKey import RSA n = 0x00a4ab66b810ae64ff4f43dd769ce0f473cf7f08c4e7e8717ae13954122932928c485096f11478938ac0983055b7ae089786967fa4d7550e4d01bf8af97cf3445f009f1b1e8933214691625cc9ddc4de280443a0a11a401efdcf44845e7bc66885f37ff6903ad2102e4ed1b1561d825b74b29701714cb79cad72aa009b7a86f82c222500d159939d9f581f9a7a7620f7799a43cda0a4d33c3097f6cddd8c27dc8398a22eb2903c7df5b36b9cd85bc3bce5c81d4fa6add2cd44496c67e1370efce43bae5d75b7b47fb1c8a6935444dd2af67a5df18c873cf3857bbce3614223706c02f118c219c44fdc8ed269484e233983a7f5f105e1f2304f0018f898c92ac205 e = 65537 d = 0x3abf5fad295e5e6feb8285bf2c66e12f740699454e8b51f909e31f083fa4683e1e0a8a5f45f36287ed001eb6660a73cc435aebfd0e49ad09722738d89b685aab1e18a55f368984449dd79eccf20eab475186230776cb0b83776fb55dd400cc078600d02152aae0d4f48fc119bcfb65cf736b863b3aa883002a59565021dd8729fcf9162f5a0d6eacc1985da86dbf7fd98ddf47d0869f8588834ecf86156e45dea6c0ae66d617c439d66d5607c09fcd7dbb6bfd872d37f598cd93969f0c4e4a2bbf03b98cef3d7c2624c81e0d70bcf4cd930c238dee5bf3d7b0894d004754a5baceab74e92cc3a96fde2296d0127f464e90d206d003f4538e1917f31cc604483d key = RSA.construct(map(long, (n,e,d))) print key.exportKey()
コードを実行してみると次のようになる。
$ python generate_pem.py -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEApKtmuBCuZP9PQ912nOD0c89/CMTn6HF64TlUEikykoxIUJbx FHiTisCYMFW3rgiXhpZ/pNdVDk0Bv4r5fPNEXwCfGx6JMyFGkWJcyd3E3igEQ6Ch GkAe/c9EhF57xmiF83/2kDrSEC5O0bFWHYJbdLKXAXFMt5ytcqoAm3qG+CwiJQDR WZOdn1gfmnp2IPd5mkPNoKTTPDCX9s3djCfcg5iiLrKQPH31s2uc2FvDvOXIHU+m rdLNRElsZ+E3DvzkO65ddbe0f7HIppNURN0q9npd8YyHPPOFe7zjYUIjcGwC8RjC GcRP3I7SaUhOIzmDp/XxBeHyME8AGPiYySrCBQIDAQABAoIBADq/X60pXl5v64KF vyxm4S90BplFTotR+QnjHwg/pGg+HgqKX0XzYoftAB62ZgpzzENa6/0OSa0Jcic4 2JtoWqseGKVfNomERJ3XnszyDqtHUYYjB3bLC4N3b7Vd1ADMB4YA0CFSquDU9I/B Gbz7Zc9za4Y7OqiDACpZVlAh3Ycp/PkWL1oNbqzBmF2obb9/2Y3fR9CGn4WIg07P hhVuRd6mwK5m1hfEOdZtVgfAn819u2v9hy039ZjNk5afDE5KK78DuYzvPXwmJMge DXC89M2TDCON7lvz17CJTQBHVKW6zqt06SzDqW/eIpbQEn9GTpDSBtAD9FOOGRfz HMYESD0CgYEA1u0Y/0SDl9vCmxowcT9+1OUXQV2ivP6lIUMN4nOSn+jGr1sV/ZqC FHWnnnunOTxlm7OdM3MyPApuUhKEmg4qrIiDM/Jn5y8fJHw8EoL++EojBOjS4CFa K3ttMjJKi9PKvzDPPL7PgXdn/p4i8P6gKMAIq/Fw6nEebFN8jTsuLSsCgYEAxCOV FbCsSl5mnEebrDdOK+B9hQbLYoVTkgnVUlxMiunMwUqW4oKwIKxIlOv0oXjJZAxQ JcoA8WTqqD33tSGY8VE5XiuzGvutiG22VRh7TNMf2aKaQHYtq+VjPcNYXy4BsEwW 4rMZFtbZ9bx3i0oaConYlIPLyIV4/LqFtIqBFY8CgYBmZ43zgreYkZMFx9KxAunx kj4kXPL/Te1sDcD91sdT/ds9Dg9KSGYWTYDSGGSy9r4LE+eg7hBPX0D1RfF8Xaej kV/CTouHMYKLJc6Rm2zU7K4G1tAzDnEiKqr6sc+nFACUXDNB5ECGlVgtjzdi0E+L WwRGuMFuUvuF7bl4qWv1BQKBgQCS2P0mxybHa1Qxz58q2iFp0mLHtSWTNrUyErCn QDmCi7dkRF8haa1KWRLihKKcPl2xzVI4aLw5/0989SA/ec8TZbeo3Nj069ep3FJ1 9aVjCHLBM+9/MbvSBiU+OcIxSLW089Lymhq/sc5wIFH0dF944mnID8ED+YJy3Yd7 e3NX2wKBgCoDehZI8U9Ri/HLoGnPt1xI5AMt+PmmXdMRNBV6cojUQAJ+QjjTdOAD eVXG7w9HAq1QQUWq0wXoB23Qa71rkb3TZcrDigcAuCSfwghX7V4FAcuXJLzd+cop Hts+sRNXTKZujJ8evbgqscMhGggSzt1k/50EQdrbX6IQ7obWz/Gb -----END RSA PRIVATE KEY----- $ python generate_pem.py | openssl rsa -noout -text Private-Key: (2048 bit) modulus: 00:a4:ab:66:b8:10:ae:64:ff:4f:43:dd:76:9c:e0: f4:73:cf:7f:08:c4:e7:e8:71:7a:e1:39:54:12:29: 32:92:8c:48:50:96:f1:14:78:93:8a:c0:98:30:55: b7:ae:08:97:86:96:7f:a4:d7:55:0e:4d:01:bf:8a: f9:7c:f3:44:5f:00:9f:1b:1e:89:33:21:46:91:62: 5c:c9:dd:c4:de:28:04:43:a0:a1:1a:40:1e:fd:cf: 44:84:5e:7b:c6:68:85:f3:7f:f6:90:3a:d2:10:2e: 4e:d1:b1:56:1d:82:5b:74:b2:97:01:71:4c:b7:9c: ad:72:aa:00:9b:7a:86:f8:2c:22:25:00:d1:59:93: 9d:9f:58:1f:9a:7a:76:20:f7:79:9a:43:cd:a0:a4: d3:3c:30:97:f6:cd:dd:8c:27:dc:83:98:a2:2e:b2: 90:3c:7d:f5:b3:6b:9c:d8:5b:c3:bc:e5:c8:1d:4f: a6:ad:d2:cd:44:49:6c:67:e1:37:0e:fc:e4:3b:ae: 5d:75:b7:b4:7f:b1:c8:a6:93:54:44:dd:2a:f6:7a: 5d:f1:8c:87:3c:f3:85:7b:bc:e3:61:42:23:70:6c: 02:f1:18:c2:19:c4:4f:dc:8e:d2:69:48:4e:23:39: 83:a7:f5:f1:05:e1:f2:30:4f:00:18:f8:98:c9:2a: c2:05 publicExponent: 65537 (0x10001) privateExponent: 3a:bf:5f:ad:29:5e:5e:6f:eb:82:85:bf:2c:66:e1: 2f:74:06:99:45:4e:8b:51:f9:09:e3:1f:08:3f:a4: 68:3e:1e:0a:8a:5f:45:f3:62:87:ed:00:1e:b6:66: 0a:73:cc:43:5a:eb:fd:0e:49:ad:09:72:27:38:d8: 9b:68:5a:ab:1e:18:a5:5f:36:89:84:44:9d:d7:9e: cc:f2:0e:ab:47:51:86:23:07:76:cb:0b:83:77:6f: b5:5d:d4:00:cc:07:86:00:d0:21:52:aa:e0:d4:f4: 8f:c1:19:bc:fb:65:cf:73:6b:86:3b:3a:a8:83:00: 2a:59:56:50:21:dd:87:29:fc:f9:16:2f:5a:0d:6e: ac:c1:98:5d:a8:6d:bf:7f:d9:8d:df:47:d0:86:9f: 85:88:83:4e:cf:86:15:6e:45:de:a6:c0:ae:66:d6: 17:c4:39:d6:6d:56:07:c0:9f:cd:7d:bb:6b:fd:87: 2d:37:f5:98:cd:93:96:9f:0c:4e:4a:2b:bf:03:b9: 8c:ef:3d:7c:26:24:c8:1e:0d:70:bc:f4:cd:93:0c: 23:8d:ee:5b:f3:d7:b0:89:4d:00:47:54:a5:ba:ce: ab:74:e9:2c:c3:a9:6f:de:22:96:d0:12:7f:46:4e: 90:d2:06:d0:03:f4:53:8e:19:17:f3:1c:c6:04:48: 3d prime1: 00:d6:ed:18:ff:44:83:97:db:c2:9b:1a:30:71:3f: 7e:d4:e5:17:41:5d:a2:bc:fe:a5:21:43:0d:e2:73: 92:9f:e8:c6:af:5b:15:fd:9a:82:14:75:a7:9e:7b: a7:39:3c:65:9b:b3:9d:33:73:32:3c:0a:6e:52:12: 84:9a:0e:2a:ac:88:83:33:f2:67:e7:2f:1f:24:7c: 3c:12:82:fe:f8:4a:23:04:e8:d2:e0:21:5a:2b:7b: 6d:32:32:4a:8b:d3:ca:bf:30:cf:3c:be:cf:81:77: 67:fe:9e:22:f0:fe:a0:28:c0:08:ab:f1:70:ea:71: 1e:6c:53:7c:8d:3b:2e:2d:2b prime2: 00:c4:23:95:15:b0:ac:4a:5e:66:9c:47:9b:ac:37: 4e:2b:e0:7d:85:06:cb:62:85:53:92:09:d5:52:5c: 4c:8a:e9:cc:c1:4a:96:e2:82:b0:20:ac:48:94:eb: f4:a1:78:c9:64:0c:50:25:ca:00:f1:64:ea:a8:3d: f7:b5:21:98:f1:51:39:5e:2b:b3:1a:fb:ad:88:6d: b6:55:18:7b:4c:d3:1f:d9:a2:9a:40:76:2d:ab:e5: 63:3d:c3:58:5f:2e:01:b0:4c:16:e2:b3:19:16:d6: d9:f5:bc:77:8b:4a:1a:0a:89:d8:94:83:cb:c8:85: 78:fc:ba:85:b4:8a:81:15:8f exponent1: 66:67:8d:f3:82:b7:98:91:93:05:c7:d2:b1:02:e9: f1:92:3e:24:5c:f2:ff:4d:ed:6c:0d:c0:fd:d6:c7: 53:fd:db:3d:0e:0f:4a:48:66:16:4d:80:d2:18:64: b2:f6:be:0b:13:e7:a0:ee:10:4f:5f:40:f5:45:f1: 7c:5d:a7:a3:91:5f:c2:4e:8b:87:31:82:8b:25:ce: 91:9b:6c:d4:ec:ae:06:d6:d0:33:0e:71:22:2a:aa: fa:b1:cf:a7:14:00:94:5c:33:41:e4:40:86:95:58: 2d:8f:37:62:d0:4f:8b:5b:04:46:b8:c1:6e:52:fb: 85:ed:b9:78:a9:6b:f5:05 exponent2: 00:92:d8:fd:26:c7:26:c7:6b:54:31:cf:9f:2a:da: 21:69:d2:62:c7:b5:25:93:36:b5:32:12:b0:a7:40: 39:82:8b:b7:64:44:5f:21:69:ad:4a:59:12:e2:84: a2:9c:3e:5d:b1:cd:52:38:68:bc:39:ff:4f:7c:f5: 20:3f:79:cf:13:65:b7:a8:dc:d8:f4:eb:d7:a9:dc: 52:75:f5:a5:63:08:72:c1:33:ef:7f:31:bb:d2:06: 25:3e:39:c2:31:48:b5:b4:f3:d2:f2:9a:1a:bf:b1: ce:70:20:51:f4:74:5f:78:e2:69:c8:0f:c1:03:f9: 82:72:dd:87:7b:7b:73:57:db coefficient: 2a:03:7a:16:48:f1:4f:51:8b:f1:cb:a0:69:cf:b7: 5c:48:e4:03:2d:f8:f9:a6:5d:d3:11:34:15:7a:72: 88:d4:40:02:7e:42:38:d3:74:e0:03:79:55:c6:ef: 0f:47:02:ad:50:41:45:aa:d3:05:e8:07:6d:d0:6b: bd:6b:91:bd:d3:65:ca:c3:8a:07:00:b8:24:9f:c2: 08:57:ed:5e:05:01:cb:97:24:bc:dd:f9:ca:29:1e: db:3e:b1:13:57:4c:a6:6e:8c:9f:1e:bd:b8:2a:b1: c3:21:1a:08:12:ce:dd:64:ff:9d:04:41:da:db:5f: a2:10:ee:86:d6:cf:f1:9b
素因数分解の結果からRSA鍵を生成してみる
公開鍵nを素因数分解した結果からdを計算し、RSA鍵を生成するコードを書いた場合は次のようになる。
# generate_pem2.py from Crypto.PublicKey import RSA from Crypto.Util.number import inverse e = 65537 p = 0x00d6ed18ff448397dbc29b1a30713f7ed4e517415da2bcfea521430de273929fe8c6af5b15fd9a821475a79e7ba7393c659bb39d3373323c0a6e5212849a0e2aac888333f267e72f1f247c3c1282fef84a2304e8d2e0215a2b7b6d32324a8bd3cabf30cf3cbecf817767fe9e22f0fea028c008abf170ea711e6c537c8d3b2e2d2b q = 0x00c4239515b0ac4a5e669c479bac374e2be07d8506cb6285539209d5525c4c8ae9ccc14a96e282b020ac4894ebf4a178c9640c5025ca00f164eaa83df7b52198f151395e2bb31afbad886db655187b4cd31fd9a29a40762dabe5633dc3585f2e01b04c16e2b31916d6d9f5bc778b4a1a0a89d89483cbc88578fcba85b48a81158f n = p*q d = inverse(e, (p-1)*(q-1)) key = RSA.construct(map(long, (n,e,d))) print key.exportKey()
コードを実行すると、dを与えたときと同じRSA鍵が生成されていることが確認できる。
$ python generate_pem2.py -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEApKtmuBCuZP9PQ912nOD0c89/CMTn6HF64TlUEikykoxIUJbx FHiTisCYMFW3rgiXhpZ/pNdVDk0Bv4r5fPNEXwCfGx6JMyFGkWJcyd3E3igEQ6Ch GkAe/c9EhF57xmiF83/2kDrSEC5O0bFWHYJbdLKXAXFMt5ytcqoAm3qG+CwiJQDR WZOdn1gfmnp2IPd5mkPNoKTTPDCX9s3djCfcg5iiLrKQPH31s2uc2FvDvOXIHU+m rdLNRElsZ+E3DvzkO65ddbe0f7HIppNURN0q9npd8YyHPPOFe7zjYUIjcGwC8RjC GcRP3I7SaUhOIzmDp/XxBeHyME8AGPiYySrCBQIDAQABAoIBADq/X60pXl5v64KF vyxm4S90BplFTotR+QnjHwg/pGg+HgqKX0XzYoftAB62ZgpzzENa6/0OSa0Jcic4 2JtoWqseGKVfNomERJ3XnszyDqtHUYYjB3bLC4N3b7Vd1ADMB4YA0CFSquDU9I/B Gbz7Zc9za4Y7OqiDACpZVlAh3Ycp/PkWL1oNbqzBmF2obb9/2Y3fR9CGn4WIg07P hhVuRd6mwK5m1hfEOdZtVgfAn819u2v9hy039ZjNk5afDE5KK78DuYzvPXwmJMge DXC89M2TDCON7lvz17CJTQBHVKW6zqt06SzDqW/eIpbQEn9GTpDSBtAD9FOOGRfz HMYESD0CgYEA1u0Y/0SDl9vCmxowcT9+1OUXQV2ivP6lIUMN4nOSn+jGr1sV/ZqC FHWnnnunOTxlm7OdM3MyPApuUhKEmg4qrIiDM/Jn5y8fJHw8EoL++EojBOjS4CFa K3ttMjJKi9PKvzDPPL7PgXdn/p4i8P6gKMAIq/Fw6nEebFN8jTsuLSsCgYEAxCOV FbCsSl5mnEebrDdOK+B9hQbLYoVTkgnVUlxMiunMwUqW4oKwIKxIlOv0oXjJZAxQ JcoA8WTqqD33tSGY8VE5XiuzGvutiG22VRh7TNMf2aKaQHYtq+VjPcNYXy4BsEwW 4rMZFtbZ9bx3i0oaConYlIPLyIV4/LqFtIqBFY8CgYBmZ43zgreYkZMFx9KxAunx kj4kXPL/Te1sDcD91sdT/ds9Dg9KSGYWTYDSGGSy9r4LE+eg7hBPX0D1RfF8Xaej kV/CTouHMYKLJc6Rm2zU7K4G1tAzDnEiKqr6sc+nFACUXDNB5ECGlVgtjzdi0E+L WwRGuMFuUvuF7bl4qWv1BQKBgQCS2P0mxybHa1Qxz58q2iFp0mLHtSWTNrUyErCn QDmCi7dkRF8haa1KWRLihKKcPl2xzVI4aLw5/0989SA/ec8TZbeo3Nj069ep3FJ1 9aVjCHLBM+9/MbvSBiU+OcIxSLW089Lymhq/sc5wIFH0dF944mnID8ED+YJy3Yd7 e3NX2wKBgCoDehZI8U9Ri/HLoGnPt1xI5AMt+PmmXdMRNBV6cojUQAJ+QjjTdOAD eVXG7w9HAq1QQUWq0wXoB23Qa71rkb3TZcrDigcAuCSfwghX7V4FAcuXJLzd+cop Hts+sRNXTKZujJ8evbgqscMhGggSzt1k/50EQdrbX6IQ7obWz/Gb -----END RSA PRIVATE KEY-----