soominkim Study
article thumbnail
Published 2023. 3. 5. 19:36
[API] HMAC 암호화 API
728x90

 

REST API 제작하거나 사용한다면 HAMC 기반 인증은 꼭 알아둬야 할 것입니다. 유명한 서비스의 REST APU를 사용하려면  secret access key id(보안 액세스 ID)와 secret access key(보안 엑세스 키)를 생성해서 등록해야 사용이 가능한 경우가 많기 때문입니다. 예로 AWS는 발급받은 AWS보안 액세스 키 ID를 Authorization 헤더에 추가해서 보내야하고 본문은 보안 엑세스키를 사용해서 HMAC 방식의 인증을 거쳐야 사용가능 할 수 있습니다. 또 많은 사람들이 사용하는 암호화폐거래소의 경우도 HAMC기반 서명을 헤더에 추가하여 요청해야 응답받을 수 있습니다. 이러한 방식은 내부적으로 해시 기반 메시지 인증(HAMC; Hash-based Message Authentication Code)라는 보안 기술을 기반하고 있습니다.

 

 1. HMAC

MD5나 SHA1, SHA256 같은 암호화 해시 함수는 입력에 대해서 유일한 출력을 내는 함수로 공개키 기반 구조(PKI; Public Key Infrastructure)입니다. HMAC은 암호화 해시 함수를 사용하여 Client가 보낸 메시지를 인증하는 방식으로 가볍고 구현이 용이하고 속도가 빨라서 다양하게 활용되고 있으며 특히 REST API 인증에 필수 요소로 자리잡고 있습니다.

 

HMAC사용자의 ID와 PASSWORD같이 민감한 정보를 직접 받을 필요 없이 사전에 공유한 secret key와 전송할 message를 입력받아 Hash 기반의 MAC(Message Authentication Code)를 생성해서 전송하며 서버는 secret key와 message를 기반으로 MAC을 검증해서 secret key를 소유한 Client가 보낸 메시지가 맞는지 인증할 수 있습니다.

HMAC 동작방식

REST API에서 많이 사용되는 HMAC-SHA256을 기준으로 HMAC을 사용하는 인증은 아래의 Wikipedia에 있는 pseudocode 처럼 다음 절차로 진행됩니다.

더보기
function hmac is
    input:
        key:        Bytes     // Array of bytes
        message:    Bytes     // Array of bytes to be hashed
        hash:       Function  // The hash function to use (e.g. SHA-1)
        blockSize:  Integer   // The block size of the underlying hash function (e.g. 64 bytes for SHA-1)
        outputSize: Integer   // The output size of the underlying hash function (e.g. 20 bytes for SHA-1)
 
    // Keys longer than blockSize are shortened by hashing them
    if (length(key) > blockSize) then
        key ← hash(key) // Key becomes outputSize bytes long

    // Keys shorter than blockSize are padded to blockSize by padding with zeros on the right
    if (length(key) < blockSize) then
        key ← Pad(key, blockSize) // Pad key with zeros to make it blockSize bytes long

    o_key_pad ← key xor [0x5c * blockSize]   // Outer padded key
    i_key_pad ← key xor [0x36 * blockSize]   // Inner padded key

    return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where ∥ is concatenation

HMAC은 임의의 message와 secret key를 사용한 이중 해시 구조이므로 다른 입력값에 대해 같은 hash 값을 내는 해시 충돌에 대해 hash 알고리즘보다 훨씬 더 안전합니다. 하지만 더 안전하게 HMAC을 사용하려면 다음과 같은 내용을 추가하는 것이 좋습니다.

 

1. 전송시 안전한 채널(HTTPS) 사용

2. Secret Key 관리

3. Replay attach 방지

 

간혹 REST API를 사용하다보면 timestamp를 요청하는 경우가 있습니다. 이런 경우가 바로 더 안전한 HMAC을 이용하기 위한 Replay attach 방지의 방법 중 하나입니다.

 

2. 전자서명을 사용하지 않는 이유

HMAC보다 더 견고하고 안전한 방식은 PKI 기반의 전자서명입니다. 하지만  이 방법은 Client에게 인증서를 발급하고 등록 및 분실/만료시 재발급/갱신 해야하는 부담이 있습니다. 특히 PKI는 HMAC 방식에 비해서 많은 연산이 필요하고 서버 부하가 많이 생기고 속도면에서 뒤처진다는 단점이 있습니다.  그래서 REST API 등에는 HMAC을 사용하고 전자계약등 사용자 부인방지(Non-Repudation)가 필요한 업무에는 PKI를 사용합니다.

728x90
profile

soominkim Study

@soominkim

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그