API Gateway 사례로 본 HMAC 인증 이해NHN 에서는 모바일 프로젝트와 관련된 다양한 제휴를 위해, 일관된 방식으로 API를 외부에 제공하는 API Gateway를 개발하여 사용하고 있습니다. API Gateway는 일반에 공개된 인터넷망을 사용하기 때문에, 위,변조 같은 보안 위협에 한층 더 노출되어 있습니다. 오늘, 인가된 사용자나 모바일 어플리케이션(이하 '앱')만 API에 접속할 수 있도록 하는 보안 기법에 초점을 맞추어 소개해 드리려 합니다.
- 스니커(sneaker)을 어떻게 막을 것인가?
- 사외에 배포된 앱이나 서버에서 사내의 서비스에 접근하기 위해 경유할 때, API Gateway를 통하게 됩니다.
API Gateway는 사내 서비스에 대한 접근 통제(인증 및 권한), 데이터 포맷 변환, 로깅 등의 역할을 수행합니다. API Gateway를 통해 제공되는 API 중의 상당수는 NHN을 통해 배포되는 앱 혹은 제휴된 앱 등을 통해 독점적으로 사용됩니다. 따라서 허가 받지 못한 접근은 원천적으로 막아야 합니다.
API Gateway에서 서버의 접근을 통제하는 것은 쉽습니다. IP address를 변조하는 IP Spoofing에 대한 가능성만 제외하면, IP address를 확인하여 체크하면 됩니다. 그러나 앱의 경우는 조금 다릅니다. 일단 불특정 다수의 디바이스에 설치되기 때문에 address를 통해 정상과 비정상 접속 요청을 구분하는 것이 불가능합니다. 이런 경우 어떤 방법을 사용할 수 있을까요? - 네트워크 보안 공격의 4가지 유형
- 실제 방법을 설명하기 전에, 먼저 네트워크를 통한 보안 공격의 유형을 살펴보겠습니다. 서비스거부공격(Denial of Service)같은 무력화 공격을 제외한다면, 대략 다음의 4가지로 나뉠 수 있습니다. 첫째는 Spoofing으로 정상경로나 사용자인 것처럼 속여서 접근을 하는 것입니다. 둘째는 Sniffing으로 서버로 전송되는 정보를 가로채는 것입니다. Hijacking은 이름 그대로 정보를 가로챈 후 변조하여 전송하는 것 입니다. 마지막의 Phishing은 필자가 추가한 유형으로 진짜 서버가 아닌 가짜 서버로 전송을 하도록 하는 것 입니다.
[네트워크 보안 공격의 4가지 유형]
일반적으로 보안 공격은 4가지가 혼재되어 사용이 되며, 대부분 최종적인 목적은 Spoofing입니다. 예를 들어, Phishing을 통해 사용자의 정보를 빼낸 후 그 정보를 이용해 Spoofing을 하거나, Sniffing을 통해 사용자의 정보를 찾아낸 후 Spoofing을 시도하는 방식입니다. 이 중, Sniffing과 Hijacking은 SSL 과 쿠키 암호화를 사용하는 것으로 대부분 막을 수 있습니다. 물론, SSL을 사용할 경우 부하가 증가하는 문제 등이 있으므로, 꼭 필요한 부분에만 사용하면 됩니다. Phishing의 경우는 대부분 XSS(Cross Site Scripting)을 통해 시도하므로, 이것 역시 어느 정도 회피가 가능합니다.
항상 SSL을 사용한다면 문제가 없겠지만, SSL을 사용하지 않는 상황에서는 쿠키 암호화에도 문제가 있습니다.
일반적으로 replay attack이라고 부르며, 암호화된 내용을 풀지는 못하지만, 그 내용을 그대로 전송하여 사용하는 것 입니다. 그리고 암호화된 쿠키 내용을 복제하면 그 사용자로 로그인되는 것과 같습니다. 이 경우, 사용할 수 있는 방법이, 사용자의 환경을 암호화하는 것으로 일반적으로 IP address를 인증 정보와 함께 암호화하는 방식으로 replay attack을 피할 수 있습니다. 네이버, 한게임에는 이와 같은 IP 보안 방식이 이미 적용되어 있습니다. - 해싱을 통한 HMAC 기반의 인증
- 암호화 알고리즘 하면 일반적으로 대칭과 비대칭 알고리즘을 꼽습니다. 대칭 알고리즘하면 보통 DES(혹은 AES)가 떠오르고, 비대칭하면 RSA가 대표적이라고 할 수 있습니다. 예를 들어, 보내는 쪽의 비밀키로 암호화한 후, 받는 쪽의 공개키로 다시 한 번 암호화 하여, 즉 이중 암호화를 하여 보내면, 메시지가 매번 변한다는 가정하에 위의 공격 유형을 모두 무력화 할 수 있습니다. 그러나 API Gateway의 목표는 이와 같이 메시지를 암호화하는 것이 아니라, 허가된 사용자와 앱만 접속하게 하는 것이 목표입니다. 즉 호출하는 URL과 결과 XML과 같은 메시지 자체의 암호화는 필요 없으며, 유출 되어도 문제가 되는 것은 아닙니다. 이 값이 유출 되어서 안 되는 경우라면, 당연히 대칭, 비대칭 암호화 방법을 사용하여야 합니다.
단순한 인증을 위한 방식으로는 암호화 보다는 해싱이 더 적합하다고 할 수 있습니다. 예를 들어, http:// apis.naver.com/test/search.xml?q=abc 라는 요청에서 abc라는 값은 암호화가 필요없습니다. 오히려 호출한 쪽이 허가된 것임을 증명하는 credential이 필요합니다. 웹에서는 이것을 암호화된 쿠키로 사용하지만, API 호출은 웹브라우저가 아닌 앱이기 때문에 쿠키를 사용할 수 없고, 대신 HMAC을 통하게 됩니다. 따라서 호출하는 URL 맨 뒤에 자신이 인증 받았음을 증명하기 위해, 적절한 code값을 추가하여 호출하고 이것을 통해 인증하는 것입니다.
[일반적인 MAC 인증 방법]
HMAC은 Hash-based Message Authentication Code의 약자입니다. 즉, 해시 기반으로 메시지를 인증하는 코드라는 의미입니다. 일반적인 구현 방법은 다음과 같습니다.1. 보내는 쪽과 받는 쪽이 HMAC에 사용할 키를 교환합니다.
2. 보내는 쪽은 교환한 키와 메시지를 결합하여 MAC을 뽑아내고, 이것을 메시지와 함께 보냅니다.
3. 받는쪽도 받은 메시지와 키를 이용하여 MAC을 뽑아내고, 이것을 메시지와 함께 받은 MAC과 비교합니다.
HMAC에서는 일반적으로 SHA1알고리즘을 이용하여 해시 값을 만들고, 이것을 MAC으로 사용합니다.
MAC은 매우 간단하지만, 교환한 키를 알지 않고서는 쉽게 접근하기 어렵다는 것이 장점입니다. 또한, SHA1 기반의 MAC은 다양한 OS와 플랫폼에 기본 탑재되어 있고, 이를 통해 API Gateway에서는 앱별로, 그리고 필요한 경우에는 서버별로 Key를 만들어 제공하고 있습니다. - 시간을 이용한 replay attack방지
- 이제 실제 시나리오를 기반으로 어떤 식의 요청이 수행되는지 살펴보기로 합니다. 인증된 앱에서 http:/dev.apis.naver.com/nhn/hmac/hmactest.xml?param1=param1Value¶m2=param2Value 라는 주소를 호출하여 어떤 작업을 처리하고자 합니다. 이 URL을 그대로 호출할 경우에는 MAC이 포함되어 있지 않아서 인증되지 않은 요청이라는 메시지가 뜨게 됩니다. 이 URL을 MAC을 이용하게 하려면 다음과 같이 호출하여 새로운 주소를 만들어야 합니다.
위의 코드에서 encryptedUrl이 MAC이 추가된 주소이며, key는 properties 파일에서 읽어서 사용합니다.
위의 실행 결과로,
http:/dev.apis.naver.com/nhn/hmac/hmactest.xml?param1=param1Value¶m2=param2Value&msgpad=1269854070375&md=zNBv2LH5X1X%2FYD2jXBRNfsT6glA%3D 라는 주소가 만들어집니다. 이 주소를 사용하여 요청하면 원하는 결과를 얻을 수 있습니다. 그럼 해커(?)가 위의 주소를 sniffing 하여 사용하면 반복 사용할 수 있을까요? 즉 replay attack을 할 수 있느냐의 문제인데, 그 답은 msgpad에 있습니다. 이 값은 시스템 시간을 long으로 변환한 값이며, 항상 원래의 URL에 추가되도록 되어 있습니다. 웹에서 로그인시에 IP address를 포함하여 쿠키를 만드는 것과 유사합니다. HMAC을 통해 MAC을 만들기 전에 먼저 msgpad를 추가하기 때문에, 같은 parameter라고 하더라도 msgpad가 계속 변하고, 따라서 MAC도 항상 다른 값이 됩니다.
항상 신뢰할 수 있는 상대와 통신할 수 있다면, 개발자들이 이런 귀찮은(?) 부가 작업에 고민할 필요가 없을 것 입니다. 하지만 현실은 그리 녹록하지 않으니, 어쩔 수 없이 공격을 막기 위한 작업을 사전에 해두어야 합니다. 잠깐, SHA1은 이미 뚫리지 않았던가요? 뚫리기는 하였으나, 그 정도 노력을 하는 해커라면, 일단 API gateway를 사용하라고 해야 할 것 같습니다. 우리가 금융 거래에 사용하는 OTP도 SHA1으로 되어 있으니 그만큼 쉽게 뚫리지는 않는다는 의미입니다. 어차피 영원히 뚫리지 않는 보안 알고리즘은 없지 않을까 예상해 봅니다.
출처 : NHN 사내 기술 매거진 The Platform. 2011년 5월호
|