네트워크(전송) 레벨 암호화
-
가장 기본적이고 필수적인
REST API
보안 방법은 네트워크 전송 프로토콜에서HTTPS
보안 프로토콜을 사용하는 방법이다. -
HTTPS
프로토콜을 사용한다 하더라도, 메세지 자체를 암호화해서 전송하기 때문에 해킹으로 말미암은 메시지 누출 위협을 해소할 수 있다. -
그러나
HTTPS
를 사용하더라도 메시지를 낚아 채거나 변조하는 방법이 있는데 이러한 해킹 방법을 바로 중간자 공격 (Man-In-The-Middle-Attack
)이라고 한다. -
정상적인
HTTPS
통신의 경우 다음과 같이 서버에서 제공하는 인증서를 이용하여 API와 서버 상호간에 암호화된 신뢰할 수 있는 새로운 네트워크 연결을 만든다.
-
중간자 공격의 경우에는 신뢰할 수 있는 연결을 만들려고 할 때 해커가
API
클라이언트와 서버 사이에 끼어들어 온다. -
신뢰할 수 있는 연결을 만들고자 서버가 인증서를 클라이언트에 내릴 때 해커가 이 인증서가 아닌 다른 인증서를 클라이언트에게 전달하고, 다른 인증서를 이용하여
API
클라이언트와 해커간에 HTTPS SSL 연결을 만든다. -
그리고 서버에게서 받은 인증서를 이용해서 서커와
API
서버 간의 HTTP SSL 연결을 맺는다. 이렇게 되면 해커는 중간에서 API 클라이언트와 서버 사이에 메시지를 모두 열어보고 변조도 가능해진다. -
이러한 중간자 공격을 방지하는 방법중에는 여러가지가 있지만, 가장 손쉬운 방법은 공인인증서를 사용하고 인증서를 확인하는 것이다.
-
공인인증서는
Verisign
과 같은 기관에서 인증서에 대한 공인 인증을 해준다. 즉, 이 인증서를 발급한 사람이 누구인가에 대한 신원 정보를 가지고 있다. 이를 공인 인증서라고 하는데, 공인 인증서는 인증 기관의 서명이 되어 있다. (공인 인증기관이 인증했다는 정보가 암호화 되서 들어간다.) -
해커가 공인인증서를 사용하려면 인증 기관에 가서 개인 정보를 등록해야하고, 자체 발급한 비공인 인증서를 사용하기 때문에 이를 이용해서 체크가 가능하다. 특히 인증서 안에는 인증서를 발급한 기관의 정보와 인증서에 대한 고유 일련번호가 들어가 있기 때문에 클라이언트에서 이 값을 확인해서 내가 발급하고 인증 받은 공인 인증서인지를 점검하도록 하면 된다.
메시지 본문 암호화
-
암호화가 필요한 특정 필드만 애플리케이션 단에서 암호화하여 보내는 방법이 있다.
-
메시지를 암호화하여 통신하려면, 클라이언트와 서버가 암호화 키를 가져야하는데, 암호화키는 크게 대칭 키와 비대칭 키 알고리즘 두 가지가 있다.
-
비대칭 키 알고리즘은 암호화를 하는 키와 암호를 푸는 복호화 키가 다른 경우로, 암호화 하는 키를 공개 키(
Public Key
)라고 하고, 암호화를 푸는 키를 비밀 키(Private Key
)라고 한다. -
이 공개 키는 암호화 할 수 있지만, 반대로 암호화된 메시지는 풀 수 없으므로 누출이 되어도 안전하다. (해커가 중간에서 공개 키를 낚아 챈다하더라도 이 키로는 암호화된 메시지를 복호화할 수 없다.)
-
따라서 처음 클라이언트가 서버에 인증이 되었을 때 클라이언트에게 이 공개 키를 내리고, 이 후에 메시지를 이 공개 키를 통해서 암호화를 하게 되면 암호화된 메시지는 비밀키를 가진 서버만이 풀 수 있어서 안전하게 서버로 메시지를 보낼 수 있다.
-
대표적인 비대칭 키 알고리즘으로는
RSA
등이 있으며 익숙한HTTPS
의 경우에도, 이RSA
알고리즘을 사용한다.RSA
알고리즘을 사용하는 비대칭 키 암호화 로직과 라이브러리등은 공개된 것들이 많으므로 참고해서 사용하도록 한다. -
비대칭 키 알고리즘은 클라이언트에서 서버로 보내는 단방향 메시지에 대해서는 암호화하여 사용할 수 있지만, 반대로 서버에서 클라이언트로 내려오는 응답 메시지 등에는 적용하기 어렵다. 아니면 클라이언트가 서버에 등록될 때, 위와 반대 방법으로 클라이언트가 서버로 공개 키를 보내서 향후 서버에서 클라이언트로 통신에 그 공개 키를 사용하도록 해도 된다.
-
이 경우에는 클라이언트와 서버 그리고 서버와 클라이언트 간의 키 쌍 두개를 관리해야 하기 때문에 복잡할 수 있는데, 이런 때에는 대칭 키 알고리즘을 고려해 볼 수 있다.
-
대칭 키 알고리즘은 암호화와 복호화 키가 같은 알고리즘이다. 이 경우
API
클라이언트와 서버가 같은 키를 알고 있어야 한다. 키를 네트워크를 통해서 보내면 중간에 해커에 의해서 낚아 채일 염려가 있기 때문에, 양쪽에 안전하게 키를 전송하는 방법이 필요하다. 따라서 다음과 같은 방법을 사용한다.
1. 서버에서 공개 키 KA1과 비공개 키 KA2 쌍을 생성한다.
2. 클라이언트에게 공개 키 KA1을 네트워크를 통해서 내려 보낸다.
3. 클라이언트는 새로운 비공개 대칭 키 KB를 생성하고 KA1을 이용하여 암호화하여 서버로 전송한다.
4. 서버는 전송된 암호화 메세지를 `KA2`로 복호화하여 그 안에 있는 비 공개 키 KB를 꺼낸다.
5. 향후 클라이언트와 서버는 상호 API 통신시 비공개 대칭 키 KB를 이용하여 암호화와 복호화를 진행한다.
메시지 무결성 보장
-
무결성이란 서버에서
API
호출을 받았을 때, 이 호출이 신뢰할 수 있는 호출인지 아닌지를 구별하는 방법을 말한다. -
즉, 해커가 중간에서 메시지를 가로채고 나서 내용을 변조하여 서버에 보냈을 때 내용이 변조되었는지를 판단하는 방법인데, 일반적으로
HMAC
을 이용한 방식이 널리 사용된다.
1. 먼저 클라이언트는 호출하고자 하는 REST API의 메시지를 앞에서 정의한 키를 이용하여 HMAC 알고리즘을 이용하여 해시 값을 추출한다.
2. API를 호출할 때, 메시지에 추출한 HMAC을 포함해서 호출한다.
3. 서버는 호출된 메시지를 보고 HMAC을 제외한 나머지 메시지를 미리 정의된 키를 이용해서 HMAC 알고리즘으로 해시 값을 추출한다.
4. 서버는 3버에서 생성된 HMAC 값과 API 호출시 같이 넘어온 HMAC 갑을 비교해서 값이 같으면 이 호출이 유효한 호출이라고 판단한다.
-
만약에 해커가 메시지를 중간에 가로채 변조했을 경우 서버에서 해시를 생성하면 변조된 메시지에 대한 해시가 생성되기 때문에, 클라이언트에서 변조 전에 보낸 해시 값과 달라진다.
-
이를 통해서 메시지 변조의 여부를 판단할 수 있다.
-
그러나 메시지를 변경하지 않고 해커가 같은 요청을 반복해서 보낸다면 메시지를 변조하지 않았다는 것으로, 서버는 이를 유효한 호출로 인식할 수 있는데 이를 재전송 공격(
Reply Attack
)이라고 한다. 따라서 이를 방지하기 위해서는timestamp
를 이용하는 방법이 있다. -
이 방법은
HMAC
을 생성할 때, 메시지를 이용해서 해시 값을 생성하는 것이 아니라, 타임 스탬프를 포함해서 메시지를 생성하는 것이다. -
그리고
API
를 호출할 때timestamp
값을 같이 실어 보낸다.
http://service.myapi.com/restapiservice?xxxxx&hmac={hashvalue}×tamp={호출시간}
- 이렇게 하면 서버는 메세지가 호출된 시간을 알 수 있고, 호출된 시간 +- 10분(또는 개발자가 정한 시간 폭)만큼의 호출만 정상적인 호출로 인식하고 시간이 지난 호출의 메시지는 비정상적인 호출로 무시하면 된다.
참고 문헌
>> Home