OpenSSL을 쓰면 돈 들이지 않고 자체 서명한 사설 인증서를 만들 수 있다. openssl은 윈도우와 리눅스에서 모두 사용할 수 있는데 대부분의 리눅스 배포판에 openssl이 설치되어 있기 때문에 VM 환경이 있으면 리눅스에서 하면 된다.
버전 확인을 했을 때 버전이 나오면 설치가 되어 있는 거다.
[root@localhost ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL 사설 인증서 생성하기
대략적인 순서는
- 루트 인증서 키 생성 (rootca.key)
- 루트 인증서 CSR 생성 (rootca.csr)
- 자체 서명 루트 인증서 생성 (rootca.crt)
- 서버 인증서 키 생성 (server.key)
- 서버 인증서 CSR 생성 (server.csr)
- 자체 서명 서버 인증서 생성 (server.crt)
- 루트 인증서를 포함하는 서버 인증서 생성 (server.pem)
이다.
이 과정을 마무리하면 서버에 설치할 server.pem, server.key 파일과 클라이언트에 설치할 rootca.crt 파일이 남게 된다.
1. 루트 인증서 키 생성
루트 인증서 키를 생성한다.
[root@localhost ssl]# openssl ecparam -out rootca.key -name prime256v1 -genkey
정상적으로 생성되면 파일을 확인해본다. 개인키를 담고 있는 걸 알 수 있다.
[root@localhost ssl]# ls
rootca.key
[root@localhost ssl]# cat rootca.key
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIN5lBuKI849fvRoXIHCJwbM+yM1X182AmHtFuF5OMsnboAoGCCqGSM49
AwEHoUQDQgAELxkBsXMAIQKSpr5M6RGNUqCS3pOf3bDHdk29qMImfrUlUq8aEyLv
tWqMqyO5zIs+gAPE1+ZRwPvL28kug0FseQ==
-----END EC PRIVATE KEY-----
2. 루트 인증서 CSR 생성
루트 인증서 CSR을 생성한다.
CSR(Certificate Signing Request)은 인증 기관에 제출하는 일종의 요청서다. 여기에 인증서에 포함할 공개키(아까 만든 rootca.key), 인증서 소유자 정보, 도메인 이름 같은 정보를 담는다.
[root@localhost ssl]# openssl req -new -sha256 -key rootca.key -out rootca.csr
CSR 생성을 요청하면 이런 저런 정보를 입력하라고 나온다. 입력해 준다.
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:KR
State or Province Name (full name) []:Seoul
Locality Name (eg, city) [Default City]:Gangnam
Organization Name (eg, company) [Default Company Ltd]:binwrite
Organizational Unit Name (eg, section) []:binwrite
Common Name (eg, your name or your server's hostname) []:binwrite. CA Root Certi ficate
Email Address []:binwrite@email.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: 공백으로 Enter 누른다
An optional company name []: 공백으로 Enter 누른다
[root@localhost ssl]#
rootca.csr 파일이 생성된 걸 확인한다.
[root@localhost ssl]# ls
rootca.csr rootca.key
[root@localhost ssl]# cat rootca.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIBXTCCAQMCAQAwgaAxCzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVTZW91bDEQMA4G
A1UEBwwHR2FuZ25hbTERMA8GA1UECgwIYmlud3JpdGUxETAPBgNVBAsMCGJpbndy
aXRlMSYwJAYDVQQDDB1iaW53cml0ZS4gQ0EgUm9vdCBDZXJ0aWZpY2F0ZTEhMB8G
CSqGSIb3DQEJARYSYmlud3JpdGVAZW1haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAELxkBsXMAIQKSpr5M6RGNUqCS3pOf3bDHdk29qMImfrUlUq8aEyLv
tWqMqyO5zIs+gAPE1+ZRwPvL28kug0FseaAAMAoGCCqGSM49BAMCA0gAMEUCIQD1
aVX9pwoQk9yDrGVshkEBYBJ0C/VgaY0DEqVI6rlHOwIgS8WuSJ7MONeNgC+YbDXl
dzERUK84+HMJNSO51eACgEs=
-----END CERTIFICATE REQUEST-----
3. 자체 서명 루트 인증서 생성
CSR를 이용해서 자체 서명한 루트 인증서를 생성한다. 이때 인증서 유효기간을 몇일로 할지 -days 옵션으로 정하는데 최대치는 999999일로 사실상 무제한으로 만들 수 있다.
[root@localhost ssl]# openssl x509 -req -sha256 -days 999999 -in rootca.csr -signkey rootca.key -out rootca.crt
Signature ok
subject=/C=KR/ST=Seoul/L=Gangnam/O=binwrite/OU=binwrite/CN=binwrite. CA Root Certificate/emailAddress=binwrite@email.com
Getting Private key
생성된 rootca.crt 파일을 확인한다.
[root@localhost ssl]# ls
rootca.crt rootca.csr rootca.key
[root@localhost ssl]# cat rootca.crt
-----BEGIN CERTIFICATE-----
MIICNDCCAdoCCQDPxnSXBH6AQjAKBggqhkjOPQQDAjCBoDELMAkGA1UEBhMCS1Ix
DjAMBgNVBAgMBVNlb3VsMRAwDgYDVQQHDAdHYW5nbmFtMREwDwYDVQQKDAhiaW53
cml0ZTERMA8GA1UECwwIYmlud3JpdGUxJjAkBgNVBAMMHWJpbndyaXRlLiBDQSBS
b290IENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJiaW53cml0ZUBlbWFpbC5j
b20wIBcNMjMxMjE2MDkyMjMzWhgPNDc2MTExMTEwOTIyMzNaMIGgMQswCQYDVQQG
EwJLUjEOMAwGA1UECAwFU2VvdWwxEDAOBgNVBAcMB0dhbmduYW0xETAPBgNVBAoM
CGJpbndyaXRlMREwDwYDVQQLDAhiaW53cml0ZTEmMCQGA1UEAwwdYmlud3JpdGUu
IENBIFJvb3QgQ2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmJpbndyaXRlQGVt
YWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC8ZAbFzACECkqa+TOkR
jVKgkt6Tn92wx3ZNvajCJn61JVKvGhMi77VqjKsjucyLPoADxNfmUcD7y9vJLoNB
bHkwCgYIKoZIzj0EAwIDSAAwRQIhAM56SOrTlz7TmmYb+gwyJAjiVlw7pp7PhIpX
68cq2nImAiAiguV+EtUb/DkEo2Bk48BfPFoIg0V4dZYjMmyI7++/tQ==
-----END CERTIFICATE-----
4. 서버 인증서 키 생성
[root@localhost ssl]# openssl ecparam -out server.key -name prime256v1 -genkey
생성된 server.key를 확인해본다.
[root@localhost ssl]# ls
rootca.crt rootca.csr rootca.key server.key
[root@localhost ssl]# cat server.key
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFfFE0PD4Lp67BGtBDQxLfMX8b9jUOEszAtK/cVfzlWPoAoGCCqGSM49
AwEHoUQDQgAE2yUmdEyQl4j03S0CBvigs8QbKIeOoBtohmf+4L1YOAP9yEnqz9SQ
PJLXftlqqGz2aFCGLTe5zCcRI/rGkHEwzw==
-----END EC PRIVATE KEY-----
5. 서버 인증서 CSR 생성
루트 인증서 CSR을 생성하는 것과 비슷하다. 다만 주의해야 할 건 서버 인증서 CSR의 Common Name은 루트 인증서의 CSR과 다르다. 서버 인증서 CSR에는 SSL 인증서를 적용할 사이트의 도메인이나 IP를 넣어준다.
[root@localhost ssl]# openssl req -new -sha256 -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:KR
State or Province Name (full name) []:Seoul
Locality Name (eg, city) [Default City]:Gangnam
Organization Name (eg, company) [Default Company Ltd]:binwrite
Organizational Unit Name (eg, section) []:binwrite
Common Name (eg, your name or your server's hostname) []:*.binwrite.com
Email Address []:binwrite@email.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
생성된 server.csr을 확인한다.
[root@localhost ssl]# ls
rootca.crt rootca.csr rootca.key server.csr server.key
[root@localhost ssl]# cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIBTjCB9AIBADCBkTELMAkGA1UEBhMCS1IxDjAMBgNVBAgMBVNlb3VsMRAwDgYD
VQQHDAdHYW5nbmFtMREwDwYDVQQKDAhiaW53cml0ZTERMA8GA1UECwwIYmlud3Jp
dGUxFzAVBgNVBAMMDiouYmlud3JpdGUuY29tMSEwHwYJKoZIhvcNAQkBFhJiaW53
cml0ZUBlbWFpbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATbJSZ0TJCX
iPTdLQIG+KCzxBsoh46gG2iGZ/7gvVg4A/3ISerP1JA8ktd+2WqobPZoUIYtN7nM
JxEj+saQcTDPoAAwCgYIKoZIzj0EAwIDSQAwRgIhAJ8SNRtEPPfvexNfkqzm3X1H
SNrHDk9Htsfq0w8wRuIAAiEAj3GLqRjYwmLsc4f5mOuHWGghLDJYho6fZe26V86M
6xM=
-----END CERTIFICATE REQUEST-----
6. 자체 서명 서버 인증서 생성
루트 인증서(rootca.crt), 루트 인증서 키(rootca.key), 서버 인증서 CSR(server.csr)를 사용해서 서버 인증서를 생성한다.
[root@localhost ssl]# openssl x509 -req -in server.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out server.crt -days 999999 -sha256
Signature ok
subject=/C=KR/ST=Seoul/L=Gangnam/O=binwrite/OU=binwrite/CN=*.binwrite.com/emailAddress=binwrite@email.com
Getting CA Private Key
생성된 server.crt를 확인한다.
[root@localhost ssl]# ls
rootca.crt rootca.key server.crt server.key
rootca.csr rootca.srl server.csr
[root@localhost ssl]# cat server.crt
-----BEGIN CERTIFICATE-----
MIICJjCCAcsCCQC+rEssrBgsMTAKBggqhkjOPQQDAjCBoDELMAkGA1UEBhMCS1Ix
DjAMBgNVBAgMBVNlb3VsMRAwDgYDVQQHDAdHYW5nbmFtMREwDwYDVQQKDAhiaW53
cml0ZTERMA8GA1UECwwIYmlud3JpdGUxJjAkBgNVBAMMHWJpbndyaXRlLiBDQSBS
b290IENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJiaW53cml0ZUBlbWFpbC5j
b20wIBcNMjMxMjE2MDkzMTEyWhgPNDc2MTExMTEwOTMxMTJaMIGRMQswCQYDVQQG
EwJLUjEOMAwGA1UECAwFU2VvdWwxEDAOBgNVBAcMB0dhbmduYW0xETAPBgNVBAoM
CGJpbndyaXRlMREwDwYDVQQLDAhiaW53cml0ZTEXMBUGA1UEAwwOKi5iaW53cml0
ZS5jb20xITAfBgkqhkiG9w0BCQEWEmJpbndyaXRlQGVtYWlsLmNvbTBZMBMGByqG
SM49AgEGCCqGSM49AwEHA0IABNslJnRMkJeI9N0tAgb4oLPEGyiHjqAbaIZn/uC9
WDgD/chJ6s/UkDyS137Zaqhs9mhQhi03ucwnESP6xpBxMM8wCgYIKoZIzj0EAwID
SQAwRgIhAKZXZLh9VIjsnRDQ80ETeNAfGUn4ePMFpAVSqiS71KJcAiEArngVBn8w
N5fZsIUd7gVb8TlLdfmICWJZ8fopXG/Al9A=
-----END CERTIFICATE-----
7. 루트 인증서를 포함하는 서버 인증서 생성
이제 서버에 넣어서 쓸 수 있는 형태로 만들기 위해 루트 인증서 + 서버 인증서 형태로 파일을 합친다.
[root@localhost ssl]# cat server.crt rootca.crt > server.pem
생성한 server.pem 파일을 확인한다.
[root@localhost ssl]# ls
rootca.crt rootca.key server.crt server.key
rootca.csr rootca.srl server.csr server.pem
[root@localhost ssl]# cat server.pem
-----BEGIN CERTIFICATE-----
MIICJjCCAcsCCQC+rEssrBgsMTAKBggqhkjOPQQDAjCBoDELMAkGA1UEBhMCS1Ix
DjAMBgNVBAgMBVNlb3VsMRAwDgYDVQQHDAdHYW5nbmFtMREwDwYDVQQKDAhiaW53
cml0ZTERMA8GA1UECwwIYmlud3JpdGUxJjAkBgNVBAMMHWJpbndyaXRlLiBDQSBS
b290IENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJiaW53cml0ZUBlbWFpbC5j
b20wIBcNMjMxMjE2MDkzMTEyWhgPNDc2MTExMTEwOTMxMTJaMIGRMQswCQYDVQQG
EwJLUjEOMAwGA1UECAwFU2VvdWwxEDAOBgNVBAcMB0dhbmduYW0xETAPBgNVBAoM
CGJpbndyaXRlMREwDwYDVQQLDAhiaW53cml0ZTEXMBUGA1UEAwwOKi5iaW53cml0
ZS5jb20xITAfBgkqhkiG9w0BCQEWEmJpbndyaXRlQGVtYWlsLmNvbTBZMBMGByqG
SM49AgEGCCqGSM49AwEHA0IABNslJnRMkJeI9N0tAgb4oLPEGyiHjqAbaIZn/uC9
WDgD/chJ6s/UkDyS137Zaqhs9mhQhi03ucwnESP6xpBxMM8wCgYIKoZIzj0EAwID
SQAwRgIhAKZXZLh9VIjsnRDQ80ETeNAfGUn4ePMFpAVSqiS71KJcAiEArngVBn8w
N5fZsIUd7gVb8TlLdfmICWJZ8fopXG/Al9A=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICNDCCAdoCCQDPxnSXBH6AQjAKBggqhkjOPQQDAjCBoDELMAkGA1UEBhMCS1Ix
DjAMBgNVBAgMBVNlb3VsMRAwDgYDVQQHDAdHYW5nbmFtMREwDwYDVQQKDAhiaW53
cml0ZTERMA8GA1UECwwIYmlud3JpdGUxJjAkBgNVBAMMHWJpbndyaXRlLiBDQSBS
b290IENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJiaW53cml0ZUBlbWFpbC5j
b20wIBcNMjMxMjE2MDkyMjMzWhgPNDc2MTExMTEwOTIyMzNaMIGgMQswCQYDVQQG
EwJLUjEOMAwGA1UECAwFU2VvdWwxEDAOBgNVBAcMB0dhbmduYW0xETAPBgNVBAoM
CGJpbndyaXRlMREwDwYDVQQLDAhiaW53cml0ZTEmMCQGA1UEAwwdYmlud3JpdGUu
IENBIFJvb3QgQ2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmJpbndyaXRlQGVt
YWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC8ZAbFzACECkqa+TOkR
jVKgkt6Tn92wx3ZNvajCJn61JVKvGhMi77VqjKsjucyLPoADxNfmUcD7y9vJLoNB
bHkwCgYIKoZIzj0EAwIDSAAwRQIhAM56SOrTlz7TmmYb+gwyJAjiVlw7pp7PhIpX
68cq2nImAiAiguV+EtUb/DkEo2Bk48BfPFoIg0V4dZYjMmyI7++/tQ==
-----END CERTIFICATE-----
인증서 확인
윈도우에선 GUI로 확인이 가능하기 때문에 이해가 좀 더 쉽다.
서버 인증서(server.crt)를 보면 인증서의 발급자를 확인할 수 없는 걸 볼 수 있는데 루트 인증서(rootca.crt)가 신뢰할 수 있는 인증 기관에 등록되어 있지 않기 때문이다.
rootca.crt를 신뢰할 수 있는 루트 인증 기관에 설치하면
서버 인증서의 체인 구조도 정상적으로 보이고 인증서를 인식한다.