티스토리 뷰
1. 암호화의 필요성과 구분
라이브 서비스를 제공하다보면, 사용자의 개인정보를 서버와 주고 받을 일이 생긴다.
이 때 나쁜 마음을 먹은 누군가가 서버와 클라이언트가 주고 받는 패킷을 가로채버린다면? 개인 정보가 그대로 누출된다. 때문에, 서버와 클라이언트가 중요한 데이터를 주고 받을 때는 암호화를 해줄 필요가 있다.
또, 서비스가 로그인/로그아웃 기능을 제공한다면 비밀번호를 서버에 저장해야한다. 그런데 이 비밀번호가 암호화가 되어있지 않다면? DB가 털리면 모든 계정 정보가 털리게 된다. 당연하지만, 비밀번호도 암호화를 해줘야한다.
하지만, 두 암호화엔 차이가 있다.
- 라이브 서비스에서 암호화된 개인정보는 대부분 이를 재활용하여 다른 정보를 제공하기 위함이라 암호화된 정보를 복호화할 수 있어야한다.
- 비밀번호 암호화의 경우엔, 로그인/로그아웃 시 입력한 비밀번호가 맞냐, 틀리냐의 검증만 필요하기 때문에 굳이 복호화 과정이 필요없다.
여기서, 단방향 암호화와 양방향 암호화로 분류가 된다.
"2020년 12월 개정된 개인정보 암호화 조치 안내서"에 따르면 공공기관은 국가정보원의 검증대상 암호 알고리즘을 기반으로, 민간부문(법인, 단체, 개인)은 국내.외 전문기관(KISA, NIST, ECRYPT, CRYPTREC 등)이 권고하는 암호 알고리즘을 기반으로 "개인정보 보호법" 상의 개인정보 암호화에 사용할 수 있는 안전한 암호 알고리즘의 예시를 아래 표와 같이 정리했다.
대부분의 암호화 알고리즘 구현 방법들은 수학적 계산이 들어간다. 최대한 복잡하게 만들기 위해서 계산복잡도를 최대한 크게 만들려고 했다. 이러한 난이도들을 NP-Hard, NP-Complete 등으로 표현하기도 한다.
하지만 본 포스팅에서는 그렇게까지 깊게 들어가고 싶진 않기 때문에 알고리즘 자체를 분석하진 않고, 구현 과정에서 고민했던 부분과 어떤 알고리즘들이 있는지만 정리해보려 한다.
추가적으로, KISA(한국인터넷진흥원)에서 발간한 '개인정보의 암호화 조치 안내서'의 요약표이다. 내가보려고 남겨놨다.
신기한 점은 위 표에 전화번호가 없다는 것이다. 전화번호 하나만으로는 개인정보 취급을 하지 않지만, 전화번호와 함께 여러 정보를 조합해서 개인을 특정할 수 있을 때는 개인 정보가 될 수 있으니 주의해야한다. 찝찝하면 그냥 암호화하는게 편하다.
1.1 단방향 암호화
단방향 암호화는 암호화는 가능하지만 복호화가 불가능한 방법이다. 앞서 언급한 것처럼 서버가 알아서 안되는 정보인 비밀번호와 같이 복호화가 필요 없는 경우 사용된다.
위 그림과 같이 일반적으로 Hashing Algorithm을 쓰는데, 대표적으로 쓰이는 SHA가 Secure Hash Algorithm의 약자이다. 뒤에 붙는 숫자들은 비트 수이다.
1.2 양방향 암호화
양방향 암호화는 대표적으로 대칭키 암호화와 공개키 암호화가 있다. 일반적으로 암/복호화할 때 키(key)를 이용한다.
1.2.1 대칭키 암호화
대칭키 암호화는 하나의 키를 이용해 암/복호화를 한다.
암/복호화 시 같은 키를 사용하기 때문에 눈에 띄는 단점들이 있다.
- 키가 탈취되었을 때, 모든 정보가 털린다.
- 안전하게 사용하기 위해서는 모든 사용자가 서로 다른 키를 가져야 하므로 키 관리를 어떻게 할 것인가? 라는 문제에 대한 고민 필요.
- 키를 안전하게 주고 받는 방법에 대한 고민 필요.
이러한 단점들에도 보편적으로 쓰이는 이유는 공개키 암호화에 비해 암/복호화의 속도가 빠르기 때문이다. 라이브 서비스에서는 속도가 빠르다는 건 큰 장점이 될 수 있다. 대칭키 암호화는 대표적으로 AES 암호화가 있고, 이 역시 뒤에 붙는 숫자는 비트 수이다.
1.2.2 공개키 암호화
공개키 암호화는 암/복호화에 사용하는 키가 서로 다른 암호화 방식을 말한다. 소인수분해를 사용하는 RSA의 경우 256비트의 암호키를 사용할 경우, 키없이 복호화하는데 우주 나이만큼 시간이 필요하다고 한다.
위 그림을 보면 간단해 보이지만, 대칭키에 비해 조금 복잡한 방식으로 동작한다. server/client 구조에서 RSA를 적용한 방식을 설명해보면,
- client가 private key/public key를 암호화하여 server에 전달
- server가 전달받은 public key로 평문을 암호화하여 client에게 전달
- server로부터 전달받은 암호를 client가 가진 private key로 복호화
위 과정으로 동작한다. 중간 과정이 추가되기 때문에 대칭키 암호화보다 당연히 속도가 더 오래 걸린다. 약 1000배의 추가 시간 소요가 된다고하니 대칭키 알고리즘을 사용하는 이유가 있는 것 같다.
2. 그래서 어떻게 쓰는게 맞을까?
자 여기서부터 고민이 된다. 대칭키 암호화는 보안상 정말로 안전할까 불안하고, 공개키 암호화로 모든 데이터를 암호화 하기엔 서버 성능에 영향이 갈 수 있다. 이 방법이 100% 맞다고 확신할 수는 없지만, 위에 대한 대응으로 두 암호화 방식을 동시에 사용하기로 했다.
server/client 구조에서 RSA/AES 방식으로 암호화 한다 가정한다.
- client가 public key를 server에 전달
- server에선 암호화가 필요한 정보들을 AES 방식으로 암호화
- AES에서 사용한 대칭키의 키(secret key)는 public key로 암호화
- 암호화된 데이터와 대칭키를 client로 전달
- client는 reponse를 받아 private key로 대칭키를 복호화
- 복호화된 대칭키로 AES 암호화된 데이터를 복호화
위와 같이 사용했다. 허점이 있을지도 모르나 모든 사용자에게 각자 다른 대칭키를 갖게 하거나, 모든 데이터를 RSA로 암/복호화 하기엔 무리가 있다 판단해서 위와 같이 암호화를 진행했다. 더 좋은 방법이 있거나, 문제가 있다면 제보 부탁드립니다....
3. 마치며
설명하지 않은 부분도 있고, 해결하지 못한 문제가 산재해 있지만 일단은 개인정보 암호화의 방향성은 잡은 것 같다.
가장 큰 문제는 같은 자바를 쓰는 android는 암호화 포맷을 서버와 맞추는데 별 어려움이 없지만, ios는 기본 제공하는 암호화 알고리즘을 맞추는데 문제가 있는 듯하다.
이 문제를 해결해야하는데, ios와 자바에서 암호화 포맷을 맞추기 위해, 따로 설정해 주는 방법이 있는지 알아봐야한다.
공부하면 할수록 알야아할게 많다고 생각이든다..
참고 사이트
https://library.gabia.com/contents/infrahosting/9071/
https://als2019.tistory.com/88
https://m.mkexdev.net/441
'개발 > 개념공부' 카테고리의 다른 글
robots.txt (0) | 2023.03.07 |
---|---|
난 REST API를 쓰고있는가? (Feat. HTTP API) (0) | 2023.03.05 |
암호화와 Key 변환 문제 (0) | 2023.01.26 |
객체 디자인 패턴, DAO & DTO & VO (0) | 2023.01.20 |
API(Application Programming Interface)란? (0) | 2023.01.20 |
- Total
- Today
- Yesterday
- S3
- JWT
- GIT
- Log
- cache
- springboot
- 후쿠오카
- 오블완
- serverless
- lambda
- Elastic cloud
- CloudFront
- AOP
- OpenAI
- 람다
- terraform
- AWS
- elasticsearch
- OpenFeign
- openAI API
- AWS EC2
- Spring
- 티스토리챌린지
- java
- EKS
- MySQL
- ChatGPT
- docker
- Kotlin
- 스프링부트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |