메시지의 무결성과 인증을 보장하기 위해 사용되는 해시 기반의 메시지 인증 코드이다. 해시 함수와 비밀 키를 결합하여 동작하며, 메시지에 위변조가 있었는지 체크하는데 사용된다.
서로 공유된 SecretKey와 지정된 HMAC 알고리즘 방식을 적용하여 SecretKeySpec 인스턴스를 생성
=> HMAC 알고리즘은 HmacMD5, HMacSHA1, HMacSHA256, HMacSHA512 등 여러가지 방식이 있으나, 여기서는 널리 사용하는 HMacSHA256를 적용하였다.
지정된 HMAC 알고리즘을 사용하여 Mac 인스턴스 생성
1에서 만든 SecretKeySpec 인스턴스를 키로 사용하여 Mac 인스턴스 초기화
초기화된 Mac 인스턴스로 HMAC 생성
생성된 HMAC을 Base64 인코딩 후 전달받은 HMAC과 값 비교
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class HmacTest {
private static final String SECRET_KEY = "mySecretKey"; // 비밀키
private static final String SIGNATURE_ALGORITHM = "HmacSHA256"; // HMAC 생성 시 사용할 알고리즘
public static void main(String[] args) {
try {
String message = "hmac test"; // 전달받은 원본 메시지
String hmac = "9ad/hIb7ZNlwjJz4J9S28RN+GRLzYo9hFW68U6mfnb8="; // 전달 받은 HMAC 값
log.info("HMAC valid result: {}", isValidHmac(message, hmac));
} catch(Exception e) {
log.error("An error occurred while generating the HMAC.", e);
}
}
private static boolean isValidHmac(String message, String hmac) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), SIGNATURE_ALGORITHM);
Mac mac = Mac.getInstance(SIGNATURE_ALGORITHM);
mac.init(keySpec);
byte[] hash = mac.doFinal(message.getBytes("UTF-8"));
String calculatedHmac = Base64.getEncoder().encodeToString(hash);
return calculatedHmac.equals(hmac);
}
}