티스토리 뷰
개요
1) 암호에 대해 간단히 흝어보았고
2) SSL/TLS 의 동작 원리를 이해했다.
3) 이제 gRPC 에서 SSL/TLS 를 어떻게 다루면 될 지 알아보자.
- 사실 handshake 는 gRPC 가 알아서 다 해준다.
참고링크
공식사이트 설명: https://grpc.io/docs/guides/auth/
Udemy gRPC 강좌
- https://www.udemy.com/grpc-golang/learn/lecture/11018820#overview
- https://www.udemy.com/grpc-golang/learn/lecture/11018822#overview
매우 좋은 OpenSSL 활용 한글 설명
- https://www.lesstif.com/pages/viewpage.action?pageId=6979614
- https://www.lesstif.com/pages/viewpage.action?pageId=7635159
이론
gRPC 로 실제 서비스를 할때는 암호화는 기본적으로 해주자. SSL 을 사용하면 된다.
SSL만 사용하면 중간에서 데이터를 가로채어 보는게 불가능해진다. MITM (Man In The Middle)
gRPC 는 SSL 로 암호화를 할 수 있고, 인증도 할 수 있다. (encryption, authentication) - 여기서는 encryption 만 보겠음
SSL와 TLS 의 관계는?
|
SSL 로 1.0, 2.0, 3.0 까지 이어지다가 TLS 로 바뀌며 1.0, 1.1, 1.2, 1.3 까지 업데이트 되고 있다. * SSL 3.0 까지도 해킹 방법이 있는 걸로 알고 있음 |
캡처 이미지 출처: https://www.wikiwand.com/en/Transport_Layer_Security
이제 실제로 구현해보자
1) CA (Certificate Authority) 설정
2) 서버Certificate 설정
3) 서버 Certificate 서명
4) 서버에서 TLS 를 사용하도록 구현
5) 클라이언트가 TLS 를 통해 서버와 연결하도록 구현
관련 링크
- https://grpc.io/docs/guides/auth/
- https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-auth-support.md
키와 서명들을 만들어보자
Udemy 강좌에 나와있는 설명들을 참고하여 만들었다.
생성 파일 |
공유 여부 |
설명 |
rootca.key |
절대 외부 유출 불가 |
Certificate Authority 의 Private key. 외부의 CA 를 이용한다면 고객인 우리는 절대 알 수 없는 키값이다. |
rootca.crt |
클라이언트에게 공유됨 |
Certificate Authority 의 trust certificate. CA 가 클라이언트 들에게 나눠주는 것이다. - 이걸로 인증서가 CA 에서 인증해준게 맞는지를 verify 할 수 있다. |
server.key |
절대 외부 유출 불가 |
Server 의 Private key. 서버측 운영자 말고는 아무도 모르는 게 맞다. |
server.csr |
서버가 CA 에게 보냄 |
Server 가 CA 에게 인증서를 만들어달라면서 보내는 것이다. - "서버인 내가 나의 정보와 공개키를 보내줄테니" - "CA 너가 나의 인증서를 만들어 주렴" |
server.crt |
서버가 클라이언트에게 공유 |
CA 가 서명해준 서버의 인증서. Server 가 가지고 있다가 클라이언트에게 공유해줌. "나 인증받은 서버이니깐 확인해봐" |
server.pem |
절대 외부 유출 불가 |
Server 의 Private key 인 server.key 를 gRPC가 좋아하는 포맷으로 변환한 것. 이걸 가지고 클라이언트에서 보내온 메시지를 복호화 할 것이다. |
Openssl 윈도우에 설치하기
빌드된 바이너리는 다음에서 찾을 수 있다: https://wiki.openssl.org/index.php/Binaries
그 중에서 여기를 선택하여 Win64_OpenSSL v1.1.0k 를 설치하였다. https://slproweb.com/products/Win32OpenSSL.html
만드는 방법 (on Windows 10)
참고 링크
- OpenSSL 모든 명령들: https://www.openssl.org/docs/man1.1.0/man1/
- OpenSSL 명령 전반을 이해할 수 있는 CheetSheet: https://www.freecodecamp.org/news/openssl-command-cheatsheet-b441be1e8c4a/
- 매우 좋은 OpenSSL 활용 한글 설명
- https://www.lesstif.com/pages/viewpage.action?pageId=6979614
- https://www.lesstif.com/pages/viewpage.action?pageId=7635159
1) rootca.key
우리가 CA, 즉 인증기관이라고 하면, 인증하는 서명을 해주려면 비대칭키가 필요하다.
genrsa 로 인증기관의 개인키를 만들어준다.
명령어 |
openssl genrsa -aes256 -out rootca.key 2048 https://www.openssl.org/docs/man1.1.0/man1/openssl-genrsa.html | ||||||||
설명 |
|
2. rootca.crt
RootCA 에게 인증서를 발급해줄 인증기관이 없으니, 자기자신에게 이렇게 발급해준다.
이 인증서를 클라이언트에게 주면, 서버로부터 오는 (RootCA 가 인증한) 인증서를 verify 할 수 있다.
명령어 |
set SERVER_CN=localhost openssl req -new -x509 -days 365 -key rootca.key -out rootca.crt -subj "/CN=%SERVER_CN%" | ||||||||||||||||
설명 |
|
위 명령으로 만든 rootca.crt 파일을 열어보았다.
|
이전 포스팅에서 보아서 익숙한 X509 포맷이다.
1) X509 의 버전이 V3 이고 2) 일련번호는 만들어준 인증서의 일련번호 3) 서명에는 SHA256 과 RSA 가 사용되었다. 4) 여기서는 발급자와 주체가 같다. CA 와 Server 가 같다는 것 5) 유효기간은 1년으로 위에서 -days 365 로 설정한것과 같다. 6) 주체는 localhost 이다. |
아예 아래와 같이 .conf 파일을 만들어서 정보를 담은 인증서를 만들 수도 있다.
캡처한 원본 링크: https://www.lesstif.com/pages/viewpage.action?pageId=6979614
3) server.key / server.csr / server.crt
아래 과정은 명령만 공유하겠음. 위 내용을 찬찬히 따라왔다면 충분히 이해가 될 것임
cli command |
설명 |
openssl genrsa -aes256 -out server.key 2048 |
1) server 의 개인키인 server.key 를 생성하고 |
set SERVER_CN=localhost openssl req -new -key server.key -out server.csr -subj "/CN=%SERVER_CN%" |
2) RootCA 에게 인증서 생성을 요청할 server.csr 을 만들고 - 아까 위에는 있던 -x509 가 빠져있다는게 다르다. 이러면 Certificate request 가 만들어진다. - 이걸 만들어서 CA에게 주면 CA 가 인증서를 만들어주는 것이다. |
openssl x509 -req -days 365 -in server.csr -CA rootca.crt -CAkey rootca.key -set_serial 01 -out server.crt |
3) RootCA 가 인증서를 생성해준다. - server.csr 을 받아서 - x509 형식으로 - 365 일 동안 유효한 - 일련번호가 01인 인증서를 - RootCA 의 개인키인 rootca.kry 를 이용해서 - server.crt 인증서를 생성해준다. |
4) server.pem
- PKCS#8 개인키 정보 문법 표준이다. 개인키 값에 대한 문법을 정의해준다.
- 이걸 만드는 이유는 gRPC 에서 이걸 쓰기 때문이다.
명령어 |
openssl pkcs8 -topk8 -nocrypt -in server.key -out server.pem | ||||||||
설명 |
|
생성한 녀석들을 다시 한 번 정리해보자
생성 파일 |
누가 가지고 있나 |
설명 |
rootca.key |
CA 만 가지고 있으면 된다. |
인증기관인RootCA 라면 자신의 공개키, 개인키 쌍이 있어야 한다. 그래서 만든 개인키 |
rootca.crt |
CA 가 자신이 인증한 인증서를 verify 할 필요가 있는 클라이언트에게 나눠준다. |
인증기관이 만든 인증서는 인증기관의 공개키로 검증이 가능하다. - 그래서 RootCA 는 자기 자신이 서명한 인증서를 만들어서 클라이언트에게 준다. |
server.key |
서버가 가지고 있는다. |
서버도 클라이언트와 통신하기 위해서는 공개키, 개인키 쌍이 필요하다. 그래서 만든 개인키 이건 서버만이 알고 있어야 한다. |
server.csr |
서버가 하나 만들어서 CA 에게 준다. 뭐, 한번 쓰고나면 실제 통신시에 쓸 일은 없다. |
서버는 자신의 정보와 공개키를 가지고 인증서를 만들어달라는 .csr (Certificate request) 를 만들어서 CA 에게 준다. |
server.crt |
서버가 가지고 있다가 암호 통신을 원하는 클라이언트에게 전달 |
CA 가 서버에게 발급해주는 인증서이다. 서버가 접속을 요청하는 클라이언트에게 던져준다. |
server.pem |
서버가 가지고서 클라이언트가 서버의 공개키로 암호화한 메시지를 복호화 하는데 쓴다. |
서버는 개인키를 가지고 있어야는데, gRPC 에서 쓰는.pem 포맷으로 변환한 것이다. |
이렇게 생성하고 나면 실제 gRPC 통신시에 필요한 것은 3개 뿐이다.
- 실제 코드를 보면 아래 세 파일만을 쓴다. (중복되는 부분이 있어도 반복학습이라 생각하고 양해를)
생성 파일 |
누가 어디에 쓰나? |
rootca.crt |
클라이언트가 가지고 있다가, 서버가 보내온 인증서를 verify 하는데 쓴다. |
server.crt |
서버가 가지고 있다가 암호 통신을 원하는 클라이언트에게 전달 |
server.pem |
서버가 가지고서 클라이언트가 서버의 공개키로 암호화한 메시지를 복호화 하는데 쓴다. |
Golang 구현
GitHub 구현코드 링크: https://github.com/nicewook/grpc-ssltls
서버
- 서버의 개인키를 PKCS#8 포맷으로 변환한 server.pem 과
- 서버의 공개키와 정보를 담은, CA 가 만들어준 인증서인 server.crt 를 탑재해주면 끝이다. 핸드셰이킹은 gRPC 가 알아서 다 해준다.
- 아래 코드는 Secure mode 를 tls 변수로 on/off 해준다. 개념만 이해하면 이처럼 구현이 쉽다.
클라이언트
클라이언트는 rootca.crt 파일을 가지고 있다.
이것은 RootCA 가 자기 자신을 cert 해준 파일이다.
클라이언트는 이걸로 서버가 보내주는 certificate (여기서는 server.crt 파일) 를 verify 하는 것이다.
정리
서버가 자신의 certificate (RootCA 가 만들어준, 서버의 개인키와 정보가 들어있는 파일) 를 클라이언트에게 주면
클라이언트는 rootca.crt 파일로 이걸 검증할 수 있을 것이다. 그러면 핸드세이크 시작!
- tls 옵션을 true, false 의 조합으로 바꿔가며 테스트 해보면 동작여부를 더욱 알기 쉬울 것이다.
'golang' 카테고리의 다른 글
Slack Slash Command - 영한 번역(2) (0) | 2019.07.15 |
---|---|
Slack Slash Command - 영한 번역(1) (0) | 2019.07.12 |
gRPC SSL/TLS 2. SSL/TLS 에 대하여 (0) | 2019.07.01 |
gRPC SSL/TLS 1. 암호에 대하여 - 대칭키, 비대칭키, 해시 알고리즘 (0) | 2019.07.01 |
gRPC Error in Golang (0) | 2019.06.27 |
- Total
- Today
- Yesterday
- postgres
- go
- bun
- notion
- 인텔리제이
- 2023
- folklore
- 잡학툰
- pool
- agile
- ChatGPT
- 클린 애자일
- 영화
- strange
- solid
- OpenAI
- intellij
- 독서후기
- JIRA
- websocket
- Bug
- Gin
- 독서
- github
- 제이펍
- golang
- API
- 노션
- 체호프
- Shortcut
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |