이 문서는 Member Hash (이하 멤버 해시)에 대해서 설명합니다.

멤버 해시 기능(보안화 설정)이란?

멤버 해시(Member Hash)는 고객의 memberId를 HMAC-SHA256를 이용해 암호화하여 적합한 유저의 부트 요청만 허용할 수 있도록 하는 기능입니다. 보안 강화를 위해서 멤버 해시 기능을 사용하는 것을 강력하게 권장합니다.

부트에 사용하는 memberId는 각 고객을 구분할 수 있고 고유한 값이어야 하므로, 많은 고객사에서 서비스의 아이디나 이메일과 같은 정보를 사용하고 있습니다. 하지만, 이와 같이 예상하기 쉬운 정보를 memberId로 사용할 경우 제3자 역시 쉽게 다른 고객의 memberId를 유추할 수 있게 됩니다. 이 경우 제3자가 다른 고객의 정보를 이용해 부트할 수 있고, 고객의 전화번호나 채팅 기록 같은 민감한 정보를 탈취할 수 있습니다.

🚧

멤버 해시 기능은 SDK를 직접 설치한 자체 개발 사이트와, 일부의 빌더사(Cafe24, 메이크샵, 워드프레스)에서 사용 가능합니다.
일반적으로 빌더사는 연동 방식에 차이가 있어 보안화 설정이 어렵습니다.
설정 가능한 일부 빌더사는 지원을 준비중에 있습니다.

시작하기

  1. [채널 설정 > 보안 및 개발 > 보안]를 클릭합니다.
  2. 고객 정보 암호화 섹션에서 신규 발급하기를 클릭하여 시크릿 키를 발급합니다.
  3. 발급받은 시크릿 키로 HMAC-SHA256를 사용하여 사용자의 memberId를 해시하도록 설정합니다.

❗️

멤버 해시를 생성하는 주체는 시크릿 키를 안전하게 보관할 수 있어야 합니다.

서비스의 백엔드 서버와 같은 곳에서 멤버 해시를 생성해서 클라이언트에 전달하는 것을 권장합니다.

HMAC 해싱 예시

아래는 네가지 언어 (JavaScript, Python, Java, php)로 memberId를 해싱하는 예시를 제공합니다.

용어 설명

  • memberId : 유저의 식별 가능한 구분자 (id)
  • secretKey : 사용할 채널에서 발급받은 시크릿 키
  • expectedHash : 시크릿 키를 이용해 인코딩된 memberId의 기댓값
const crypto = require('crypto');

const memberId = 'lucas';
const secretKey = '4629de5def93d6a2abea6afa9bd5476d9c6cbc04223f9a2f7e517b535dde3e25';
const expectedHash = "99427c7bba36a6902c5fd6383f2fb0214d19b81023296b4bd6b9e024836afea2";

const hash = crypto.createHmac('sha256', Buffer.from(secretKey, 'hex'))
                .update(memberId)
                .digest('hex');
import hmac
import hashlib
import binascii

member_id = "lucas"
secret_key = "4629de5def93d6a2abea6afa9bd5476d9c6cbc04223f9a2f7e517b535dde3e25"
expected_hash = "99427c7bba36a6902c5fd6383f2fb0214d19b81023296b4bd6b9e024836afea2"
hash = hmac.new(
    binascii.unhexlify(bytearray(secret_key, "utf-8")),
    msg=member_id.encode('utf-8'),
    digestmod=hashlib.sha256
).hexdigest()
public static String encode(String memberId, String secretKey, String algorithms) {
  try {
    Mac mac = Mac.getInstance(algorithms);
    mac.init(new SecretKeySpec(hexify(secretKey), algorithms));

    byte[] hash = mac.doFinal(memberId.getBytes());

    StringBuilder sb = new StringBuilder(hash.length * 2);
    for (byte b: hash) {
      sb.append(String.format("%02x", b));
    }

    return sb.toString();
  }catch (Exception e) {
    throw new RuntimeException(e);
  }
}

private static byte[] hexify(String string) {
  return DatatypeConverter.parseHexBinary(string);
}
$expectedHash = hash_hmac('sha256', 'lucas', pack("H*", '4629de5def93d6a2abea6afa9bd5476d9c6cbc04223f9a2f7e517b535dde3e25'));

// $expectedHash = '99427c7bba36a6902c5fd6383f2fb0214d19b81023296b4bd6b9e024836afea2';

멤버 해시 기능의 동작

멤버 해시가 켜져있는 경우

  • 멤버 유저로 부트하는 경우

    부트 요청 시 유저의 memberId와 해시화된 값을 모두 제공해야 합니다. 채널은 이 멤버 해시가 HMAC-SHA256을 통해 정상적으로 생성된 값인지 체크합니다. 체크 뒤 기대한 값이 아니라면, 권한 오류를 응답으로 받게 됩니다.

  • 익명의 유저로 부트하는 경우

    memberId와 memberHash 값을 비운 뒤 부트합니다.

멤버 해시가 꺼져있는 경우

부트 과정에서 어느것도 검증하지 않습니다. memberHash 값은 무시됩니다.

시크릿 키와 멤버 해시 값을 확인하는 방법

  • 시크릿 키는 채널 설정 > 보안 및 개발 > 고객 정보 암호화 에서 확인할 수 있습니다. 조회하기 버튼을 눌러 시크릿 키를 조회합니다.
  • 텍스트 필드의 우측에 새로고침 버튼을 통해 시크릿 키를 재발급 할 수 있습니다.
  • “해시 검증 테스트하기” 를 통해, 멤버 해시 값이 주어진 시크릿 키로 적절히 인코딩 된 값인지 검증할 수 있습니다.

문제 해결

  • 멤버 해시 기능은 채널톡 SDK를 모두 설정 완료한 뒤에 활성화 해야 합니다. 설치가 완료되지 않은 채 기능을 활성화 하는 경우 채널톡 SDK가 동작하지 않을 수 있습니다.
  • 만약 시크릿 키가 노출된 경우, 시크릿 키를 재 발급받은 뒤 시작하기를 통해 재설정합니다.