REST API는 간결하고 효율적인 데이터 전송 방식으로 널리 사용되고 있습니다.
그러나 보안이 취약한 경우 민감한 데이터가 노출될 수 있습니다.
HMAC(Hash-based Message Authentication Code)는 이러한 보안 위협을 방지하기 위한 강력한 인증 방식입니다.
이번 글에서는 스프링 시큐리티(Spring Security)를 사용하여 REST API에 HMAC를 적용하는 방법을 알아보겠습니다.
1. HMAC란 무엇인가요?
HMAC는 해시 함수와 비밀 키를 사용하여 메시지의 무결성과 인증을 보장하는 기술입니다.
이 과정에서 메시지와 비밀 키를 결합하여 고유한 해시 값을 생성합니다.
이를 통해 데이터가 위변조되었는지 확인할 수 있습니다.
HMAC의 주요 특징
- 무결성 보장: 데이터를 전송하는 동안 수정되었는지 확인할 수 있습니다.
- 인증 기능: 비밀 키를 아는 사용자만이 올바른 HMAC 값을 생성할 수 있습니다.
- 유연성: 다양한 해시 알고리즘(SHA-256, SHA-1 등)을 사용할 수 있습니다.
HMAC 작동 방식
- 클라이언트가 요청을 생성합니다.
- 요청 데이터를 기반으로 HMAC 값을 계산합니다.
- 서버는 동일한 키와 데이터로 HMAC 값을 계산하여 클라이언트의 값과 비교합니다.
- 값이 일치하면 요청이 인증됩니다.
2. REST API에 HMAC 적용하기
스프링 시큐리티를 사용하여 HMAC를 REST API에 적용할 수 있습니다.
다음은 기본적인 구현 방법입니다.
1. HMAC 키 생성
비밀 키는 안전한 방식으로 생성해야 합니다.
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;
public class HmacKeyGenerator {
public static String generateKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
SecretKey secretKey = keyGen.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
public static void main(String[] args) throws Exception {
System.out.println("HMAC Key: " + generateKey());
}
}
위 코드는 HMAC 키를 생성하여 출력합니다.
생성된 키를 안전한 위치에 저장하세요.
2. 요청에 HMAC 헤더 추가
클라이언트는 요청 데이터와 비밀 키를 기반으로 HMAC 값을 계산하고 헤더에 추가해야 합니다.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class HmacUtil {
public static String calculateHMAC(String data, String key) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes()));
}
public static void main(String[] args) throws Exception {
String key = "your-secret-key";
String data = "request-data";
System.out.println("HMAC: " + calculateHMAC(data, key));
}
}
위 코드는 요청 데이터와 비밀 키를 기반으로 HMAC 값을 생성합니다.
생성된 HMAC 값을 HTTP 헤더에 포함시켜 요청을 전송합니다.
3. 서버에서 HMAC 검증
서버는 동일한 비밀 키로 클라이언트의 HMAC 값을 검증합니다.
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HmacValidationFilter extends OncePerRequestFilter {
private final String secretKey = "your-secret-key";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String headerHmac = request.getHeader("HMAC");
String requestData = request.getReader().lines().reduce("", String::concat);
String calculatedHmac = HmacUtil.calculateHMAC(requestData, secretKey);
if (!calculatedHmac.equals(headerHmac)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid HMAC");
return;
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "HMAC Validation Error");
return;
}
filterChain.doFilter(request, response);
}
}
}
이 필터는 모든 요청의 HMAC 값을 검증하여 위조된 요청을 차단합니다.
3. HMAC의 장점과 한계
장점
1. 데이터 무결성 보장: 데이터가 수정되지 않았는지 확인할 수 있습니다.
2. 높은 보안성: 비밀 키를 사용하는 방식으로 보안을 강화합니다.
3. 간단한 구현: 기존 REST API에 쉽게 통합할 수 있습니다.
한계
1. 키 관리 필요: 비밀 키가 노출되면 보안이 취약해질 수 있습니다.
2. 추가 작업 요구: 클라이언트와 서버 모두 HMAC 처리 로직이 필요합니다.
4. 결론
HMAC는 REST API의 보안을 강화하는 데 매우 유용한 도구입니다.
스프링 시큐리티와 함께 사용하면 간단하고 효과적으로 API를 보호할 수 있습니다.
HMAC를 활용하여 신뢰할 수 있는 API 서비스를 구축해보세요! 😊
'스프링 시큐리티와 보안 가이드' 카테고리의 다른 글
[Spring Security] Spring Boot Actuator와 보안 설정 (0) | 2025.01.26 |
---|---|
[Spring Security] Spring Security의 FilterChain 구조 완벽 이해 (0) | 2025.01.25 |
[Spring Security] 스프링시큐리티에서 Role과 Authority의 차이 및 활용법 (1) | 2025.01.23 |