2018/05/31

[Cryptography] RSA private key & public key PEM之解析和驗證

這次要動手來驗證RSA的理論與實際操作Openssl產生的key pair是否一致。



按照理論是,私鑰public key會是(modulus, e);而公鑰private key則是(modulus, d),其中
e*d = 1 mod φ(N)

首先先利用Openssl產生2048 bits的私鑰及公鑰。
$ openssl genrsa -out key.pem 2048
$ openssl rsa -in key.pem -pubout -out pubkey.pem

值得注意的是,產生完私鑰的結果,有直接把public exponent的e直接寫出來,也就是65537。

檔案內容:
key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA3twsjJQ9UCk9M5WMsX46BE/hmBxccV4Ti4vu7hyfU1wQHiK3
Di4MCybn8DrZS3vM+vuqWiq9VMlIkKeY3f3iTOh7yiIeYgqPz8DZFM//p3WriOev
S2oXc7yjzn2mfZ7iKrZXk626KCm/1l0ZlfFe6Nl2/3ooMu4eAcW5RZQGen5R4ShF
jNQpQfqUT95Ce+xK4Xf4Roc6C/I8EVBHX5LlBaURCvc+lX0jR9aaeAWVnMiXyUYF
V2ViQkoUwUGPRKs/AcX3t4x8Bo/NfKqPrdcaAJx5q1BNqAwLcKhHXtuCCPcIUMeC
fWoYadiTMFq+okuv+4Q4iePHQV6T6URhFS0ryQIDAQABAoIBAQCotA15QcKESyOM
SBpgRoiOuRWye02zeB7dlUmCsOIfTWLaHTdroYn2azZK0ZGqpYYPPLHBXfdDFrg6
4NREwCsuQxNqeZd8ajhhccAjFC2Yy+fVVGWLdj1YnKV37AA7uinFYZE8NtfkDW6u
TH3Q1w4cwHpnfUau/zhx6QaOWDbrRAhr3ThboVUWs2mmA9B6s0dGUUVvf98eTEok
sv0zw0tJ8zMyDTnXQWorkWXnH/oe+3nA8jp3PJouCoGT8Ej9S+yyw03oJRVSpVpi
iiLohpKHqRqFeH5KbnoEmBtm6KBkCAmb6+NuMYabyluFRSYTh5Wnovia88tUeoab
xm4yX9iBAoGBAPzGyDuACXYkQyLMq/jRr90LZvvpDv1UYv8MIrP9UijvI8GGiYzR
QQ+mfwxT8gK8Jw3jHUvD4EdJLZr8JpiZ1io5QhLF+vnAN0B/k6BrEd76G40Rwi/M
IwL3E0WyKueJQ7g6aAo/709NK0X/4Bpe8FeT0xOEhTpJmkuT2EOFWeXRAoGBAOGz
uemRT6RXqEKtQnJgOa8ZQPilVVyZxzlCL410wSz2//nY5d1LiEoy6XYKU/Si+suK
AmCzXjYQ0Y1kRU7d3y37W62GyM129MYkmR9uuiwN+4iT55rpDz3d2SQg9+ublrzh
A7MohPO9BLKCwQ903B74svxMKMkfl+4/DYpb/cx5AoGAf4I6kSEWJL1IDG7YNQx5
PPS6f0piIFIIGgXiH48iebmf/MhD7H/F5QIkxnA1/UEyJiQxq/1jzjHQyoR1Z7b6
PJRjixrJbmCSvntcWaiI/ESHz1Js9TVxV9aQpzCnyeIJAg6cWsdDjWos8QOQ5VyM
unC8IfVQS0XDimpKxkynO3ECgYEAyEBxLBWcZwDLLlWRRe+wXnX2mmX+5cke5OOf
U0+K8b05AlF6KS0SAFtJnkytjrln8V1CnM+oQCoN8vhLMh1THfYNslmLIhlwNblV
Dnlsvxes29H2xRARUN/b/90seqOyS2UNplDGHYfQeh3e8zrI7sXT8FwWN9RLNbxF
5EOYXGkCgYEAnnYN/Qe7yfx8g0O08YEbMWBrTadSV5IR44YautL+4dv+NgZv0mml
HsJQ3DnY2gEMfZo6HbVrOS0ewtEj4HW5XTiFjL8dZm8LfkyhuW6q8YPKS91hEecg
6FpxBQsWvS9899U938J4LiHpED+m/L52SYj84h2mDXl2UDkc8iYFTgk=
-----END RSA PRIVATE KEY-----

pubkey.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3twsjJQ9UCk9M5WMsX46
BE/hmBxccV4Ti4vu7hyfU1wQHiK3Di4MCybn8DrZS3vM+vuqWiq9VMlIkKeY3f3i
TOh7yiIeYgqPz8DZFM//p3WriOevS2oXc7yjzn2mfZ7iKrZXk626KCm/1l0ZlfFe
6Nl2/3ooMu4eAcW5RZQGen5R4ShFjNQpQfqUT95Ce+xK4Xf4Roc6C/I8EVBHX5Ll
BaURCvc+lX0jR9aaeAWVnMiXyUYFV2ViQkoUwUGPRKs/AcX3t4x8Bo/NfKqPrdca
AJx5q1BNqAwLcKhHXtuCCPcIUMeCfWoYadiTMFq+okuv+4Q4iePHQV6T6URhFS0r
yQIDAQAB
-----END PUBLIC KEY-----

但這樣其實看不懂,轉換成明文:
$openssl rsa -in key.pem -text -out private.text

private.text
Private-Key: (2048 bit)
modulus:
    00:de:dc:2c:8c:94:3d:50:29:3d:33:95:8c:b1:7e:
    3a:04:4f:e1:98:1c:5c:71:5e:13:8b:8b:ee:ee:1c:
    9f:53:5c:10:1e:22:b7:0e:2e:0c:0b:26:e7:f0:3a:
    d9:4b:7b:cc:fa:fb:aa:5a:2a:bd:54:c9:48:90:a7:
    98:dd:fd:e2:4c:e8:7b:ca:22:1e:62:0a:8f:cf:c0:
    d9:14:cf:ff:a7:75:ab:88:e7:af:4b:6a:17:73:bc:
    a3:ce:7d:a6:7d:9e:e2:2a:b6:57:93:ad:ba:28:29:
    bf:d6:5d:19:95:f1:5e:e8:d9:76:ff:7a:28:32:ee:
    1e:01:c5:b9:45:94:06:7a:7e:51:e1:28:45:8c:d4:
    29:41:fa:94:4f:de:42:7b:ec:4a:e1:77:f8:46:87:
    3a:0b:f2:3c:11:50:47:5f:92:e5:05:a5:11:0a:f7:
    3e:95:7d:23:47:d6:9a:78:05:95:9c:c8:97:c9:46:
    05:57:65:62:42:4a:14:c1:41:8f:44:ab:3f:01:c5:
    f7:b7:8c:7c:06:8f:cd:7c:aa:8f:ad:d7:1a:00:9c:
    79:ab:50:4d:a8:0c:0b:70:a8:47:5e:db:82:08:f7:
    08:50:c7:82:7d:6a:18:69:d8:93:30:5a:be:a2:4b:
    af:fb:84:38:89:e3:c7:41:5e:93:e9:44:61:15:2d:
    2b:c9
publicExponent: 65537 (0x10001)
privateExponent:
    00:a8:b4:0d:79:41:c2:84:4b:23:8c:48:1a:60:46:
    88:8e:b9:15:b2:7b:4d:b3:78:1e:dd:95:49:82:b0:
    e2:1f:4d:62:da:1d:37:6b:a1:89:f6:6b:36:4a:d1:
    91:aa:a5:86:0f:3c:b1:c1:5d:f7:43:16:b8:3a:e0:
    d4:44:c0:2b:2e:43:13:6a:79:97:7c:6a:38:61:71:
    c0:23:14:2d:98:cb:e7:d5:54:65:8b:76:3d:58:9c:
    a5:77:ec:00:3b:ba:29:c5:61:91:3c:36:d7:e4:0d:
    6e:ae:4c:7d:d0:d7:0e:1c:c0:7a:67:7d:46:ae:ff:
    38:71:e9:06:8e:58:36:eb:44:08:6b:dd:38:5b:a1:
    55:16:b3:69:a6:03:d0:7a:b3:47:46:51:45:6f:7f:
    df:1e:4c:4a:24:b2:fd:33:c3:4b:49:f3:33:32:0d:
    39:d7:41:6a:2b:91:65:e7:1f:fa:1e:fb:79:c0:f2:
    3a:77:3c:9a:2e:0a:81:93:f0:48:fd:4b:ec:b2:c3:
    4d:e8:25:15:52:a5:5a:62:8a:22:e8:86:92:87:a9:
    1a:85:78:7e:4a:6e:7a:04:98:1b:66:e8:a0:64:08:
    09:9b:eb:e3:6e:31:86:9b:ca:5b:85:45:26:13:87:
    95:a7:a2:f8:9a:f3:cb:54:7a:86:9b:c6:6e:32:5f:
    d8:81
prime1:
    00:fc:c6:c8:3b:80:09:76:24:43:22:cc:ab:f8:d1:
    af:dd:0b:66:fb:e9:0e:fd:54:62:ff:0c:22:b3:fd:
    52:28:ef:23:c1:86:89:8c:d1:41:0f:a6:7f:0c:53:
    f2:02:bc:27:0d:e3:1d:4b:c3:e0:47:49:2d:9a:fc:
    26:98:99:d6:2a:39:42:12:c5:fa:f9:c0:37:40:7f:
    93:a0:6b:11:de:fa:1b:8d:11:c2:2f:cc:23:02:f7:
    13:45:b2:2a:e7:89:43:b8:3a:68:0a:3f:ef:4f:4d:
    2b:45:ff:e0:1a:5e:f0:57:93:d3:13:84:85:3a:49:
    9a:4b:93:d8:43:85:59:e5:d1
prime2:
    00:e1:b3:b9:e9:91:4f:a4:57:a8:42:ad:42:72:60:
    39:af:19:40:f8:a5:55:5c:99:c7:39:42:2f:8d:74:
    c1:2c:f6:ff:f9:d8:e5:dd:4b:88:4a:32:e9:76:0a:
    53:f4:a2:fa:cb:8a:02:60:b3:5e:36:10:d1:8d:64:
    45:4e:dd:df:2d:fb:5b:ad:86:c8:cd:76:f4:c6:24:
    99:1f:6e:ba:2c:0d:fb:88:93:e7:9a:e9:0f:3d:dd:
    d9:24:20:f7:eb:9b:96:bc:e1:03:b3:28:84:f3:bd:
    04:b2:82:c1:0f:74:dc:1e:f8:b2:fc:4c:28:c9:1f:
    97:ee:3f:0d:8a:5b:fd:cc:79
exponent1:
    7f:82:3a:91:21:16:24:bd:48:0c:6e:d8:35:0c:79:
    3c:f4:ba:7f:4a:62:20:52:08:1a:05:e2:1f:8f:22:
    79:b9:9f:fc:c8:43:ec:7f:c5:e5:02:24:c6:70:35:
    fd:41:32:26:24:31:ab:fd:63:ce:31:d0:ca:84:75:
    67:b6:fa:3c:94:63:8b:1a:c9:6e:60:92:be:7b:5c:
    59:a8:88:fc:44:87:cf:52:6c:f5:35:71:57:d6:90:
    a7:30:a7:c9:e2:09:02:0e:9c:5a:c7:43:8d:6a:2c:
    f1:03:90:e5:5c:8c:ba:70:bc:21:f5:50:4b:45:c3:
    8a:6a:4a:c6:4c:a7:3b:71
exponent2:
    00:c8:40:71:2c:15:9c:67:00:cb:2e:55:91:45:ef:
    b0:5e:75:f6:9a:65:fe:e5:c9:1e:e4:e3:9f:53:4f:
    8a:f1:bd:39:02:51:7a:29:2d:12:00:5b:49:9e:4c:
    ad:8e:b9:67:f1:5d:42:9c:cf:a8:40:2a:0d:f2:f8:
    4b:32:1d:53:1d:f6:0d:b2:59:8b:22:19:70:35:b9:
    55:0e:79:6c:bf:17:ac:db:d1:f6:c5:10:11:50:df:
    db:ff:dd:2c:7a:a3:b2:4b:65:0d:a6:50:c6:1d:87:
    d0:7a:1d:de:f3:3a:c8:ee:c5:d3:f0:5c:16:37:d4:
    4b:35:bc:45:e4:43:98:5c:69
coefficient:
    00:9e:76:0d:fd:07:bb:c9:fc:7c:83:43:b4:f1:81:
    1b:31:60:6b:4d:a7:52:57:92:11:e3:86:1a:ba:d2:
    fe:e1:db:fe:36:06:6f:d2:69:a5:1e:c2:50:dc:39:
    d8:da:01:0c:7d:9a:3a:1d:b5:6b:39:2d:1e:c2:d1:
    23:e0:75:b9:5d:38:85:8c:bf:1d:66:6f:0b:7e:4c:
    a1:b9:6e:aa:f1:83:ca:4b:dd:61:11:e7:20:e8:5a:
    71:05:0b:16:bd:2f:7c:f7:d5:3d:df:c2:78:2e:21:
    e9:10:3f:a6:fc:be:76:49:88:fc:e2:1d:a6:0d:79:
    76:50:39:1c:f2:26:05:4e:09
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA3twsjJQ9UCk9M5WMsX46BE/hmBxccV4Ti4vu7hyfU1wQHiK3
Di4MCybn8DrZS3vM+vuqWiq9VMlIkKeY3f3iTOh7yiIeYgqPz8DZFM//p3WriOev
S2oXc7yjzn2mfZ7iKrZXk626KCm/1l0ZlfFe6Nl2/3ooMu4eAcW5RZQGen5R4ShF
jNQpQfqUT95Ce+xK4Xf4Roc6C/I8EVBHX5LlBaURCvc+lX0jR9aaeAWVnMiXyUYF
V2ViQkoUwUGPRKs/AcX3t4x8Bo/NfKqPrdcaAJx5q1BNqAwLcKhHXtuCCPcIUMeC
fWoYadiTMFq+okuv+4Q4iePHQV6T6URhFS0ryQIDAQABAoIBAQCotA15QcKESyOM
SBpgRoiOuRWye02zeB7dlUmCsOIfTWLaHTdroYn2azZK0ZGqpYYPPLHBXfdDFrg6
4NREwCsuQxNqeZd8ajhhccAjFC2Yy+fVVGWLdj1YnKV37AA7uinFYZE8NtfkDW6u
TH3Q1w4cwHpnfUau/zhx6QaOWDbrRAhr3ThboVUWs2mmA9B6s0dGUUVvf98eTEok
sv0zw0tJ8zMyDTnXQWorkWXnH/oe+3nA8jp3PJouCoGT8Ej9S+yyw03oJRVSpVpi
iiLohpKHqRqFeH5KbnoEmBtm6KBkCAmb6+NuMYabyluFRSYTh5Wnovia88tUeoab
xm4yX9iBAoGBAPzGyDuACXYkQyLMq/jRr90LZvvpDv1UYv8MIrP9UijvI8GGiYzR
QQ+mfwxT8gK8Jw3jHUvD4EdJLZr8JpiZ1io5QhLF+vnAN0B/k6BrEd76G40Rwi/M
IwL3E0WyKueJQ7g6aAo/709NK0X/4Bpe8FeT0xOEhTpJmkuT2EOFWeXRAoGBAOGz
uemRT6RXqEKtQnJgOa8ZQPilVVyZxzlCL410wSz2//nY5d1LiEoy6XYKU/Si+suK
AmCzXjYQ0Y1kRU7d3y37W62GyM129MYkmR9uuiwN+4iT55rpDz3d2SQg9+ublrzh
A7MohPO9BLKCwQ903B74svxMKMkfl+4/DYpb/cx5AoGAf4I6kSEWJL1IDG7YNQx5
PPS6f0piIFIIGgXiH48iebmf/MhD7H/F5QIkxnA1/UEyJiQxq/1jzjHQyoR1Z7b6
PJRjixrJbmCSvntcWaiI/ESHz1Js9TVxV9aQpzCnyeIJAg6cWsdDjWos8QOQ5VyM
unC8IfVQS0XDimpKxkynO3ECgYEAyEBxLBWcZwDLLlWRRe+wXnX2mmX+5cke5OOf
U0+K8b05AlF6KS0SAFtJnkytjrln8V1CnM+oQCoN8vhLMh1THfYNslmLIhlwNblV
Dnlsvxes29H2xRARUN/b/90seqOyS2UNplDGHYfQeh3e8zrI7sXT8FwWN9RLNbxF
5EOYXGkCgYEAnnYN/Qe7yfx8g0O08YEbMWBrTadSV5IR44YautL+4dv+NgZv0mml
HsJQ3DnY2gEMfZo6HbVrOS0ewtEj4HW5XTiFjL8dZm8LfkyhuW6q8YPKS91hEecg
6FpxBQsWvS9899U938J4LiHpED+m/L52SYj84h2mDXl2UDkc8iYFTgk=
-----END RSA PRIVATE KEY-----

可以看到檔案包含了:
1. modulus,就是兩個質數prime 1 * prime 2的結果,應該是2048 bits
2. 兩個指數e, d,e是public exponent;d是private exponent

再來看看公鑰的部分:
$ openssl rsa -inform PEM -pubin -text -noout < pubkey.pem

可以看到modulus和exponent與私鑰的內容相同,所以其實可以說在產生私鑰的時候,公鑰已經包含在裡面了

所以利用python來驗證:
#!/usr/bin/env python
import gmpy2
from gmpy2 import mpz

modulus = mpz(0x00dedc2c8c943d50293d33958cb17e3a044fe1981c5c715e138b8beeee1c9f535c101e22b70e2e0c0b26e7f03ad94b7bccfafbaa5a2abd54c94890a798ddfde24ce87bca221e620a8fcfc0d914cfffa775ab88e7af4b6a1773bca3ce7da67d9ee22ab65793adba2829bfd65d1995f15ee8d976ff7a2832ee1e01c5b94594067a7e51e128458cd42941fa944fde427bec4ae177f846873a0bf23c1150475f92e505a5110af73e957d2347d69a7805959cc897c94605576562424a14c1418f44ab3f01c5f7b78c7c068fcd7caa8fadd71a009c79ab504da80c0b70a8475edb8208f70850c7827d6a1869d893305abea24baffb843889e3c7415e93e94461152d2bc9)
privateExponent = mpz(0x00a8b40d7941c2844b238c481a6046888eb915b27b4db3781edd954982b0e21f4d62da1d376ba189f66b364ad191aaa5860f3cb1c15df74316b83ae0d444c02b2e43136a79977c6a386171c023142d98cbe7d554658b763d589ca577ec003bba29c561913c36d7e40d6eae4c7dd0d70e1cc07a677d46aeff3871e9068e5836eb44086bdd385ba15516b369a603d07ab3474651456f7fdf1e4c4a24b2fd33c34b49f333320d39d7416a2b9165e71ffa1efb79c0f23a773c9a2e0a8193f048fd4becb2c34de8251552a55a628a22e8869287a91a85787e4a6e7a04981b66e8a06408099bebe36e31869bca5b854526138795a7a2f89af3cb547a869bc66e325fd881)
publicExponent = mpz(65537)

prime1 = mpz(0x00fcc6c83b800976244322ccabf8d1afdd0b66fbe90efd5462ff0c22b3fd5228ef23c186898cd1410fa67f0c53f202bc270de31d4bc3e047492d9afc269899d62a394212c5faf9c037407f93a06b11defa1b8d11c22fcc2302f71345b22ae78943b83a680a3fef4f4d2b45ffe01a5ef05793d31384853a499a4b93d8438559e5d1)
prime2 = mpz(0x00e1b3b9e9914fa457a842ad42726039af1940f8a5555c99c739422f8d74c12cf6fff9d8e5dd4b884a32e9760a53f4a2facb8a0260b35e3610d18d64454edddf2dfb5bad86c8cd76f4c624991f6eba2c0dfb8893e79ae90f3dddd92420f7eb9b96bce103b32884f3bd04b282c10f74dc1ef8b2fc4c28c91f97ee3f0d8a5bfdcc79)
phi_N = gmpy2.mul(prime1-1, prime2-1)

print('The modulus is \n{}'.format(modulus))
print('The prime1*prime2 is \n{}'.format(gmpy2.mul(prime1, prime2)))
print('The privateExponent is \n{}'.format(privateExponent))
print('The inverse of publicExponent is \n{}'.format(gmpy2.invert(publicExponent, phi_N)))
print('The prime1 is {}bits'.format(prime1.bit_length()))
print('The modulus is {}bits'.format(modulus.bit_length()))

結果:
驗證了三件事:
1. modulus的值為prime 1 * prime 2
2. e*d = 1 mod φ(N)
3. modulus為2048 bits,而prime則是1024 bits

沒有留言:

張貼留言