OpenSSL Explained for Kubernetes
- 1. Symmetric Cryptography
- 2. Asymmetric Cryptography (Public Key)
- 3. Certificate Signing Request (CSR)
- 4. Self-Signed Certificate in Kubernetes
- Abbreviations
- References
1. Symmetric Cryptography
1.1 Explained
Symmetric Encription은 동일한 키를 사용해서 encrypt 그리고 decrypt 를 하게 됩니다.
- 일반적으로 여러개의 crypto algorithms 을 사용해서 symmetric encryption 을 만듭니다. (ex. AES-256-CBC -PBKDF2)
1.2 Generate Key and Data
Symmetric encryption algorithm 중의 하나의 aes-256-cbc
사용해서 encrypt 를 했습니다.
먼저 데이터를 생성 합니다.
# 데이터 넣기
$ echo "Hello Anderson!" > data.txt
Symmetric Key 를 생성합니다.
# Symmetric Key 생성
$ openssl rand 128 > symmetric.key
# Key값 확인
$ cat symmetric.key
Z�vfh���*"��� S3�&�n=�`+�is@����ȡ˫<���fF��I|�S<생략>
1.3 Encryption
Encryption은 다음과 같이 합니다.
-k symmetric.key
: 해당 옵션을 빼면 암호를 넣으라고 나올겁니다.
# Encrypt (데이터 + 패스워드 -> encrypted.txt)
$ openssl aes-256-cbc -pbkdf2 -base64 -in data.txt -out encrypted.txt -k symmetric.key
# 데이터 확인 (-base64 형식으로 저장됨)
$ cat encrypted.txt
U2FsdGVkX1+K/AX4sYGnasTiOmW6gLxDw4APT/3B9OVFCHizUYLe1Bbo0gPcHrYL
1.4 Decryption
Decryption는 다음과 같이 합니다.
-k symmetric.key
를 빼고 encrypt했다면, descrypt할때도 빼야 합니다.
# Decrypt (동일하게 -pbkdf2 -base64 사용)
$ openssl aes-256-cbc -d -pbkdf2 -base64 -in encrypted.txt -out descrypted.txt -k symmetric.key
# 데이터 확인
$ cat descrypted.txt
Hello Anderson!
2. Asymmetric Cryptography (Public Key)
2.1 Explained
- Public Key: Encrypt 하는 데 사용
- Private Key: Decrypt 하는 데 사용
2.2 Generate Private Key
먼저 RSA 알고리즘을 사용해서 Private Key 를 생성합니다.
-aes256
,-aria256
,-des
,-des3
등의 옵션으로 private key를 다시한번 특정 cipher로 encrypt합니다.
$ openssl genrsa -out private.key 2048
$ cat private.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA5z95XeHLsbiaaDsM+7eHqL8wtNBOrDlge47Y/pSi1g6xWuC2
u+AawKhFluJHbN4yQMS3PMQGNjVZVRCUwwSacmLXEQD/ekWoZ2RBNdmhPlg+u0kd
6iEzLIFJy3jqW324lAcY9EfC/5Rdk0y3Yc184fQK4T/h0NZ5gOwJnL3XI4uv7rhR
<많은 생략>
84u58DUCgYEAk8It6g7hGgBqBeYY7pl8dfR1d9futVwqoP4mxmVUvua4jBQfFok3
Vxzj1fKLe+srTpI5srhhBDI1sYtVsaFuaXKaP1QIHlPqB2sF5AEnEbOX5w4pS7TR
zzxqPaelCfYudRjfw/Ma5cJWu50dW30JdLcapY/8wA+F1GtJaKlFD/o=
-----END RSA PRIVATE KEY-----
이후 private.key를 갖고서 public key를 생성합니다.
2.3 Extract Public Key
$ openssl rsa -in private.key -pubout -out public.key
$ cat public.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19I1QgwX1QLmilD9odP3
dwYIX66n4pEMXXsUM5zVYVhKCo4wMeXWIE8auu3IZ+P23/rTUxY3fogesvH5dfaO
<짧은 생략>
rK29doGZeDHdqyIBqi5rzxOu8VtRWAL91+VaaYtTKhzZE3fI1VPsESayKUtKc+fX
BwIDAQAB
-----END PUBLIC KEY-----
2.4 Small File
먼저 데이터 Encrypt는 다음과 같이 합니다.
# 데이터 생성
$ echo "Hello Anderson!" > data.txt
# Encrypt data.txt
$ openssl rsautl -encrypt -pubin -inkey public.key -in data.txt -out encrypted.txt
# encrypted.txt
$ cat encrypted.txt
�2�M-/L��pw]%M�U|*���EL�#�~'&Ƃ+X�,��%*�U��>�����}�Q�����ߙ��ct���"CA�����cئ0C�w�A�"y��Ғ�gȏ�Y��`�g�SIN�����I.\
Decrypt는 다음과 같이 합니다.
$ openssl rsautl -decrypt -inkey private.key -in encrypted.txt -out decrypted.txt
$ cat decrypted.txt
Hello Anderson!
2.5 Large File
Asymmetric cryptography로 RSA 를 사용하였고, RSA의 문제는 116bytes 까지의 데이터만 encrypt 할 수 있습니다.
openssl rand 128
등의 명령어로 먼저 Symmetric Key를 생성 파일은 116 bytes를 넘을 수 없습니다.
3. Certificate Signing Request (CSR)
3.1 SSL/TLS Explained
HTTPS 모르는 사람은 없을 것이고, HTTP인데 그냥 SSL/TLS 기술로 data encryption이 들어간 protocol이라고 생각하면 됩니다.
SSL(Secure Socket Layer)은 90년대 넷스케이프에서 개발되었으며 현재는 deprecation 되었으며,
현재는 TLS(Transport Layer Security)를 주로 사용합니다.
TLS Handshake 구조를 보면 다음과 같습니다.
- Client Hello: 클라쪽 SSL버젼 정보, Cipher Suite list (지원하는 암호화 방식), 무작위 바이트 문자열 -> 서버로 보냄
- Server Hello: 암호화 방법 선택 이후 SSL Certificate, 무작위 바이트 문자열 -> 클라로 보냄
- 서버가 보낸 SSL Certificate에는 서버측 public key, 그리고 서비스 정보를 담고 있다
- CA에서 인증: 클라는 서버에서 SSL Certificate을 받았지만, 신뢰할수 있는지 확인하기 위해서 CA에서 확인을 하게 됨
- CA: certificate authority 로서 GeoTrust, IdenTrust를 의미
- 클라는 서버가 전달해준 certificate을 CA로 보냄
- certificate에서 public key를 꺼내고 CA의 private key를 사용해서 encrypted data를 decrypt함
- decrypt가 잘됐다면 CA에서 인증한 certificate이기 때문에 신뢰함
- Premaster Secret: 클라는 서버측 certificate에 있는 public key를 갖고서 premaster secret을 만들고 -> 서보로 보냄
- Private Key Used: 서버는 premaster secret을 서버측 private key 로 decrypt 한다
- Session Key Created:
SSL Certificate은 CA (Certificate Authority. 예 GeoTrust)로 부터 발급됩니다.
3.2 Generate CSR
CSR은 Certificate Signing Request의 약자로서 “인증서 서명 요청”이라는 뜻으로,
SSL Certificate을 CA로 부터 얻을때 사용합니다. 즉.. SSL Certificate 구매할때 반드시 만들어야 함.
$ openssl req -new -newkey rsa:2048 -nodes -keyout private.key -out cert.csr
Generating a RSA private key
.............................................+++++
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Gyeonggi-do
Locality Name (eg, city) []:Goyang-si
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Anderson
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:incredible.ai
Email Address []:a141890@gmail.com
잘 생성 됐는지 확인
cert.csr 파일안에 어떤 내용이 들어있는지 확인하기 위해서 다음의 명령어를 사용합니다.
국가, 주소, 이름, 회사, 도메인, 이메일 등등 정확하게 기입되었는지 확인합니다.
$ openssl req -in cert.csr -noout -text
기존 private key로 CSR생성
$ openssl req -new -out cert.csr -key private.key
3.3 Generate Self-Signed Certificate
Self-signed certificate은 보통 내부망 또는 개발환경에서 테스트시에 사용이 됩니다.
다음의 명령어로 self-signed certificate을 생성할 수 있습니다.
-x509
: self-signed certificate 이라고 알림-nodes
: no des 라는 뜻으로 암호화 하지 않겠다는 것. 이거 빼면.. 생성할때 암호 쓰라고 나옴.-new
: 국가, 이름, 회사, 도메인, 이메일 등등의 물어보는 prompt가 나오면서 새롭게 생성하게 됨cert.key
: Certificateprivate.key
: private key
$ openssl req -x509 -newkey rsa:2048 -nodes -keyout private.key -out cert.key
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Gyeonggi-do
Locality Name (eg, city) []:Goyang-si
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Anderson
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:incredible.ai
Email Address []:a141890@gmail.com
기존의 private key 그리고 CSR로 부터 Self-Signed Certificate 생성
$ openssl x509 -signkey private.key -in cert.key -req -out cert.crt
3.4 Verify
CSR
$ openssl req -text -noout -verify -in cert.csr
verify OK
Private Key
$ openssl rsa -in private.key -check
RSA key ok
SSL Certificate
$ openssl x509 -in cert.key -text -noout
SSL Certificate 그리고 Private Key 가 서로 일치하는지 확인
$ openssl x509 -noout -modulus -in cert.key | openssl md5
(stdin)= d31b4f5b1a438bb878b847062abc3e26
$ openssl rsa -noout -modulus -in private.key | openssl md5
(stdin)= d31b4f5b1a438bb878b847062abc3e26
4. Self-Signed Certificate in Kubernetes
4.1 Generate CA
CA 생성에는 두가지 방법이 있습니다.
- EKS에서 이미 만들어져 있는 것을 가져온다
- 새로 생성
EKS 에서 Private Key 가져오는 방법은 다음과 같습니다.
먼저 EKS -> Cluster -> Certificate Authority 를 복사해서
$ echo <Certificate-Authority> | base64 -d > ca.key
$ cat ca.key
-----BEGIN CERTIFICATE-----
MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIwMTAxNTE4MjczMFoXDTMwMTAxMzE4MjczMFowFTETMBEGA1UE
<생략>
3s8dl/pTqzbMwJtyRLnUHAcoYqYJiICkOWzIqSjuiNPMbSw4bWIKAc4ItQWukiGy
BcDZMt1MvWH2csacIJHMmgyOsIRqI4XyNJRr34DwMUMkMDfTrNQ8mNUPRcY=
-----END CERTIFICATE-----
CA Key를 새로 생성하는 방법은 다음과 같습니다.
- MASTER_IP: EKS Cluster에서 API Server Endpoint 를 찾아서 넣습니다. 이때 https는 뺍니다.
$ export MASTER_IP=EAA012E181CFAF7CDEB872D695DBF864.gr7.us-east-2.eks.amazonaws.com
$ openssl genrsa -out private.key 2048
$ openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out cert.key
Server Key를 발급합니다.
$ openssl genrsa -out server.key 2048
CSR (Certificate Signing Request)를 생성하기 위해서 config 파일을 생성합니다.
Abbreviations
- CSR: Certificate Signing Request
- DER: Distinguished Encoding Rules
- PEM: Privacy Enhanced Mail
- PKCS: Public-Key Cryptography Standards
- SHA: Secure Hash Algorithm
- SSL: Secure Socket Layer
- TLS: Transport Layer Security