RSA는 소인수 분해의 어려움을 이용한 비대칭 암호화 알고리즘으로써, 현재 SSL 인증서에 사용되는 대부분의 RSA 키는 2048 비트를 사용한 RSA-2048 암호화를 사용한다.
다음과 같은 방법으로 공개키와 개인키가 생성된다.
p = 3, q = 7n = p * q = 21φ(n) = (p - 1)(q - 1) = 12φ(n) = (p - 1)(q - 1)1 < e < φ(n) 이며, φ(n)와 서로소인 e를 찾는다 e = 5(e * d) % φ(n) = 1 인 d를 찾는다. d = 5 (5 * 5) % 12 = 1실제 암호 알고리즘에서는 p, q 값이 매우 크기때문에 역산할 수 없다는점을 이용한다. 또한 실제 알고리즘에서 e값은 대부분 65537 (2^16 + 1) 을 이용한다.
openssl을 사용하다 보면, 암호 알고리즘을 선정해 개인키를 만들고, 이 개인키를 통해 인증서 즉 공개키를 만든다. (인증서 내부에 공개키가 있으므로)
openssl genpkey -algorithm RSA -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt
이 과정에서 서버의 개인키를 통해 CSR을 생성하는 과정에서 공개키가 포함되며, 어떻게 RSA 개인키를 통해 공개키가 나오게 되는것인지 궁금해서 공부하게 되었다.
RSA 개인키라고 해서 나는 RSA 암호 알고리즘에서 생성된 (n, d) 개인키가 그대로 저장되는줄 알았다.
여기서 어떻게 개인키를 통해, 같이 생성된 공개키를 알 수 있냐 이것이 궁금했고 찾아보니 답을 얻을 수 있었다.
RSA 개인키는 다음과 같은 구조를 가진다.
위의 요소들이 모두 모여 개인키를 구성하고, 위와같은 정보가 있기 때문에 공개키 (n, e) 를 추출해낼 수 있는것이다.
실제 RSA 개인키를 만들어 요소를 확인해볼 수 있다.
openssl genrsa -out RSA.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDfX7oqPd+3tWpR
nP1h4yVNOz3YgjnQaqpehiE5sLxhBJHdslVVWzY5xTVl1dBg1gCZx1oRvUR3IPHt
VYJ73CEn1e/MP8TDlIziaynf1i7rJmNQTmS+/LjxnKklH/Vvt1hrfCFF6gCCS3UO
k6/7o8p6T6kykwzq7qrkJdnDHQAR7k6Gi+CGNvaTFD6G2MIg/xVNw8VT6M+vnZyK
J8REHJZQ0lzPKXJVR6m1dK34L1Ai3rJ+8gNmfXEDZFgYnb6ubJ4sjvV7kKlKdDc3
3mZPfRk7/maMZJ/+p2FaOIB11gJyHn0K0skoXH6Ph/AuWUsKKkEk1tx55QDtwp2N
+aQBVyz3AgMBAAECggEAWwG4am9tD37lQz0P6urNjsq9JtHf1i8vHHXPYZ7FEU34
U/fNVopj7GORntzfGiT2d7DF3IZdN5//kS+OiwIjrAQ4v+GXPAvw3mrE08KCuSGZ
wuU9nKaAf0fRjiOYLpzndFtNfxuYe31cwsSfJYoU+4IrMETDNZBppaxaLWlKVwMa
XaNP6bb/8N+xVk0uP5da37NPG66q8hnlR/An7zGX8DMX2pEst2lIT+5//ibzLaij
4Jv/dPODuAXoDRefaZfadMoNAB0tXPkamgN6BUHyL/qgcdEe+MFxVyU2kE8+0oyk
zEWGoi2MDQVbGQ+urpfKE5S7/5iXNyN/tn1Rdh/LoQKBgQD9zCUQv2iwYWNXGOK6
rgF9cH0OAAWPX0A/PU36LZzz7Q5o+yuQPhX5+x73JIgAn78aMbT7r99nQVEZnSLo
lrzlHOEm075QPLKrsv2+PwFX3x7u/fT5wYcf44Umqn9gkhVxgzBPMYfNzt1xL5Sa
1dLz2QtiumcVYWm5Bsnnetn4sQKBgQDhT/3GCQdODDAIyPjBnWkCRIOtIGKM01zE
L9p9kzWxbNXGgDvTh+qKAgruYYhAxSfEn4BuQ253oxdp+0bdyhJhIG7sgBa2flvL
l5xwpATCN4CEMsDoIstYtUYfExDEDCmwC5Ou/xCccMSmambFJCmBP37ktt3uxbQN
tQjKtflqJwKBgQDwqWFIZUjfYCn0EDwHKzNsgHuFCA49quPgU8CaiCA5ycONVwcz
KzxppG/ziOeSN+jd7N6if15Hqk8+C5xrk2yhkWYLDGR972C5oewtN8+NRJ0voQ9o
udPpMDU1uh05NK0yy2TG47/UL+IaDzVKMZJs+pZqUzmms42uDzrrzrncsQKBgEdu
/vxMXH6IKqp+XS+1YlePtVesTtJrKJwit9jcVUedQ+GdQlp8WwXKRADz9yjh2Qvj
repHgrx3frLhMcSbjlww1joxGgJd6WiQ9s5XkhKpWhuPo811SpcjUcoEV2pwmL7x
zK7Mu01+CzrfvRl/r5EEuox01cQf9kfqP5FVRHA9AoGAe1S35Tv1lxzt/VRuxO/h
icK9LOucZRRzEueusLwaTxOpYnp9WQCNP4fOWsBcC1YAxvs67wtaxl/xnHpJfp+k
OzqPYsuEEcgqulMFUoCYuUw1YDRdnuBXBB8heRsrbumi4EMFPIceEh0co/XdqzjV
K8K8PP6XZyx6Sv+mvU8QnsA=
-----END PRIVATE KEY-----openssl rsa -noout -text -in RSA.key
Private-Key: (2048 bit, 2 primes)
modulus:
00:df:5f:ba:2a:3d:df:b7:b5:6a:51:9c:fd:61:e3:
25:4d:3b:3d:d8:82:39:d0:6a:aa:5e:86:21:39:b0:
bc:61:04:91:dd:b2:55:55:5b:36:39:c5:35:65:d5:
d0:60:d6:00:99:c7:5a:11:bd:44:77:20:f1:ed:55:
82:7b:dc:21:27:d5:ef:cc:3f:c4:c3:94:8c:e2:6b:
29:df:d6:2e:eb:26:63:50:4e:64:be:fc:b8:f1:9c:
a9:25:1f:f5:6f:b7:58:6b:7c:21:45:ea:00:82:4b:
75:0e:93:af:fb:a3:ca:7a:4f:a9:32:93:0c:ea:ee:
aa:e4:25:d9:c3:1d:00:11:ee:4e:86:8b:e0:86:36:
f6:93:14:3e:86:d8:c2:20:ff:15:4d:c3:c5:53:e8:
cf:af:9d:9c:8a:27:c4:44:1c:96:50:d2:5c:cf:29:
72:55:47:a9:b5:74:ad:f8:2f:50:22:de:b2:7e:f2:
03:66:7d:71:03:64:58:18:9d:be:ae:6c:9e:2c:8e:
f5:7b:90:a9:4a:74:37:37:de:66:4f:7d:19:3b:fe:
66:8c:64:9f:fe:a7:61:5a:38:80:75:d6:02:72:1e:
7d:0a:d2:c9:28:5c:7e:8f:87:f0:2e:59:4b:0a:2a:
41:24:d6:dc:79:e5:00:ed:c2:9d:8d:f9:a4:01:57:
2c:f7
publicExponent: 65537 (0x10001)
privateExponent:
5b:01:b8:6a:6f:6d:0f:7e:e5:43:3d:0f:ea:ea:cd:
8e:ca:bd:26:d1:df:d6:2f:2f:1c:75:cf:61:9e:c5:
11:4d:f8:53:f7:cd:56:8a:63:ec:63:91:9e:dc:df:
1a:24:f6:77:b0:c5:dc:86:5d:37:9f:ff:91:2f:8e:
8b:02:23:ac:04:38:bf:e1:97:3c:0b:f0:de:6a:c4:
d3:c2:82:b9:21:99:c2:e5:3d:9c:a6:80:7f:47:d1:
8e:23:98:2e:9c:e7:74:5b:4d:7f:1b:98:7b:7d:5c:
c2:c4:9f:25:8a:14:fb:82:2b:30:44:c3:35:90:69:
a5:ac:5a:2d:69:4a:57:03:1a:5d:a3:4f:e9:b6:ff:
f0:df:b1:56:4d:2e:3f:97:5a:df:b3:4f:1b:ae:aa:
f2:19:e5:47:f0:27:ef:31:97:f0:33:17:da:91:2c:
b7:69:48:4f:ee:7f:fe:26:f3:2d:a8:a3:e0:9b:ff:
74:f3:83:b8:05:e8:0d:17:9f:69:97:da:74:ca:0d:
00:1d:2d:5c:f9:1a:9a:03:7a:05:41:f2:2f:fa:a0:
71:d1:1e:f8:c1:71:57:25:36:90:4f:3e:d2:8c:a4:
cc:45:86:a2:2d:8c:0d:05:5b:19:0f:ae:ae:97:ca:
13:94:bb:ff:98:97:37:23:7f:b6:7d:51:76:1f:cb:
a1
prime1:
00:fd:cc:25:10:bf:68:b0:61:63:57:18:e2:ba:ae:
01:7d:70:7d:0e:00:05:8f:5f:40:3f:3d:4d:fa:2d:
9c:f3:ed:0e:68:fb:2b:90:3e:15:f9:fb:1e:f7:24:
88:00:9f:bf:1a:31:b4:fb:af:df:67:41:51:19:9d:
22:e8:96:bc:e5:1c:e1:26:d3:be:50:3c:b2:ab:b2:
fd:be:3f:01:57:df:1e:ee:fd:f4:f9:c1:87:1f:e3:
85:26:aa:7f:60:92:15:71:83:30:4f:31:87:cd:ce:
dd:71:2f:94:9a:d5:d2:f3:d9:0b:62:ba:67:15:61:
69:b9:06:c9:e7:7a:d9:f8:b1
prime2:
00:e1:4f:fd:c6:09:07:4e:0c:30:08:c8:f8:c1:9d:
69:02:44:83:ad:20:62:8c:d3:5c:c4:2f:da:7d:93:
35:b1:6c:d5:c6:80:3b:d3:87:ea:8a:02:0a:ee:61:
88:40:c5:27:c4:9f:80:6e:43:6e:77:a3:17:69:fb:
46:dd:ca:12:61:20:6e:ec:80:16:b6:7e:5b:cb:97:
9c:70:a4:04:c2:37:80:84:32:c0:e8:22:cb:58:b5:
46:1f:13:10:c4:0c:29:b0:0b:93:ae:ff:10:9c:70:
c4:a6:6a:66:c5:24:29:81:3f:7e:e4:b6:dd:ee:c5:
b4:0d:b5:08:ca:b5:f9:6a:27
exponent1:
00:f0:a9:61:48:65:48:df:60:29:f4:10:3c:07:2b:
33:6c:80:7b:85:08:0e:3d:aa:e3:e0:53:c0:9a:88:
20:39:c9:c3:8d:57:07:33:2b:3c:69:a4:6f:f3:88:
e7:92:37:e8:dd:ec:de:a2:7f:5e:47:aa:4f:3e:0b:
9c:6b:93:6c:a1:91:66:0b:0c:64:7d:ef:60:b9:a1:
ec:2d:37:cf:8d:44:9d:2f:a1:0f:68:b9:d3:e9:30:
35:35:ba:1d:39:34:ad:32:cb:64:c6:e3:bf:d4:2f:
e2:1a:0f:35:4a:31:92:6c:fa:96:6a:53:39:a6:b3:
8d:ae:0f:3a:eb:ce:b9:dc:b1
exponent2:
47:6e:fe:fc:4c:5c:7e:88:2a:aa:7e:5d:2f:b5:62:
57:8f:b5:57:ac:4e:d2:6b:28:9c:22:b7:d8:dc:55:
47:9d:43:e1:9d:42:5a:7c:5b:05:ca:44:00:f3:f7:
28:e1:d9:0b:e3:ad:ea:47:82:bc:77:7e:b2:e1:31:
c4:9b:8e:5c:30:d6:3a:31:1a:02:5d:e9:68:90:f6:
ce:57:92:12:a9:5a:1b:8f:a3:cd:75:4a:97:23:51:
ca:04:57:6a:70:98:be:f1:cc:ae:cc:bb:4d:7e:0b:
3a:df:bd:19:7f:af:91:04:ba:8c:74:d5:c4:1f:f6:
47:ea:3f:91:55:44:70:3d
coefficient:
7b:54:b7:e5:3b:f5:97:1c:ed:fd:54:6e:c4:ef:e1:
89:c2:bd:2c:eb:9c:65:14:73:12:e7:ae:b0:bc:1a:
4f:13:a9:62:7a:7d:59:00:8d:3f:87:ce:5a:c0:5c:
0b:56:00:c6:fb:3a:ef:0b:5a:c6:5f:f1:9c:7a:49:
7e:9f:a4:3b:3a:8f:62:cb:84:11:c8:2a:ba:53:05:
52:80:98:b9:4c:35:60:34:5d:9e:e0:57:04:1f:21:
79:1b:2b:6e:e9:a2:e0:43:05:3c:87:1e:12:1d:1c:
a3:f5:dd:ab:38:d5:2b:c2:bc:3c:fe:97:67:2c:7a:
4a:ff:a6:bd:4f:10:9e:c0PKCS(Public Key Cryptography Standard) 는 공개키 암호에 대한 표준이며 여러가지 표준들이 존재하고, 현재는 사장된 표준또한 있다. 그중 #1 과 #8 에 대해 알아본다.
RFC 3447: Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1
PKCS #1 은 RSA 암호화 표준이다.
RSA만을 다루며, 키의 구조, 데이터를 암. 복호화 하는 방식등을 다루는 표준이다.
PKCS #8은 개인키 정보에 대한 표준이다.
개인키 자체를 인코딩하기 위한 표준을 정의하며, RSA와 같은 특정 알고리즘에 종속되지 않는다.
즉 #1 은 RSA에 대한 표준이며, #8 은 개인키에 대한 표준이다
openssl 에서 만들어지는 RSA 개인키는 일반적으로 PKCS #8 표준을 따르는 키다.
만약 필요한 경우 #8 ⇒ #1, #1 ⇒ #8 로 상호 교환이 가능하다.
openssl pkcs8 -topk8 [-nocrypt] -in PKCS1.pem -out PKCS8.pem
openssl pkey -in PKCS8.pem -traditional -out PKCS1.pem

PKCS1.pem, PKCS8.pem 비교
두 키를 비교해보면 키 자체는 다르지만, 실제 저장된 RSA 요소는 동일하다.
키와 같은 암호화 요소들을 인코딩 하기 위한 규칙들이 몇가지 있다.
데이터를 이진 형식으로 인코딩 하기 위한 규칙이다. ASN.1 표준으로 키를 바이너리 인코딩한다.
이진 인코딩이기 때문에 사람이 직접 볼 수 없고, 다른 툴을 사용해야지 값을 확인할 수 있다.
전자메일을 위한 보안기능 표준이였으나, 현재는 키와같은 암호자료를 인코딩하는데 사용된다.
일반적으로 데이터를 base64로 인코딩한 후, 헤더와 푸터를 추가한 방식이다.
-----BEGIN ...-----
...data
-----END ...-----
헤더와 푸터는 - 를 양끝에 5개씩 쓰고, 데이터의 종류를 기입한다 ex)
-----BEGIN PRIVATE KEY----- : PKCS #1 키-----BEGIN RSA PRIVATE KEY----- : PKCS #8 키-----BEGIN CERTIFICATE----- : 인증서이 헤더를 통해 PKCS #1 인지, PKCS #8인지도 확인할 수 있다.
RSA 개인키는 여러 데이터를 포함하고 있다. (Modulus, Public Exponent, Private Exponent 등…)
이 데이터를 어떠한 포맷으로 저장할지를 결정하는것이 키의 포맷 PKCS #8등 이며, 현재 RSA 키를 만드는 경우 대부분 PKCS #8 포맷으로 키가 만들어진다.
이렇게 만든 키를 인코딩까지 하게되면 우리가 항상 보던 private 키가 완성이 된다. 인코딩은 PEM방식을 주로 사용하며 이렇게 완성된 키는 다음과 같은 모습을 띄게된다.

암호화 되지 않은 RSA private key

암호화된 RSA private key