HMAC (keyed-Hash Message Authentication Code)
데이터를 보낼 때 데이터와 함께 해당 데이터를 해싱처리한 HMAC의 값을 함께 보냄으로써 수신자의 입장에서 해당 데이터가 위변조가 되었는지 안되었는지 파악할 수 있게 해준다.
이를 이용하려면 우선 요청자, 수신자 간의 약속이 2가지 필요하다.
SecretKey 와 Algorithm 두가지를 서로 공유하고 있어야한다.
데이터를 같은 방식으로 암호화를 하여야 HMAC 값이 동일하게 나오며 같음 여부에 따라 위변조를 파악 할 수 있기 때문
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class HmacEncrypt {
private static final String SECRETKEY = "TEST";
private static final String WRONGKEY = "TEXT";
private static final String ALGORITHMS = "HmacSHA512";
public static String encode(String secretKey, String algorithms, String msg) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
Mac haser = Mac.getInstance(ALGORITHMS);
haser.init(new SecretKeySpec(SECRETKEY.getBytes("utf-8"), ALGORITHMS));
byte[] hash = haser.doFinal(msg.getBytes());
return Base64.encodeBase64String(hash);
}
}
아래 결과 처럼 받은 데이터를 encoding한 것과 받은 hmac의 값이 동일 할 경우에만 위/변조 되어있지 않다는 것을 확인할 수 있으며 예시의 경우는 짧은 문자열인지라 굳이 왜하는가 생각할 수 있지만 내용이 엄청나게 많은 XML 파일의 내용이라던가 깊이가 매우 깊은 JSON 데이터등이라고 한다면 이를 일일히 확인할 수 없다. 그렇기 때문에 서로 신뢰할 수 있는 통신임을 확인하기 위해서 이를 사용하는 것이다.
package com.example.demo.controller;
import com.example.demo.encrypt.HmacEncrypt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@RestController
public class HomeController {
@GetMapping("/test")
public String test() throws InvalidKeyException, NoSuchAlgorithmException {
String msg = "Hello, HMAC!";
String algorithms = "HmacSHA512";
String secretKey = "TEST";
String wrongKey = "TEXT";
String hmac = HmacEncrypt.encode(secretKey, algorithms, msg);
String hmac2 = HmacEncrypt.encode(secretKey, algorithms, msg);
String forseryHmac = HmacEncrypt.encode(secretKey, algorithms, msg + "123");
String wrongKeyHmac = HmacEncrypt.encode(wrongKey, algorithms, msg);
return msg + "<br>" + hmac + "<br>" + hmac2 + "<br>" + forseryHmac + "<br>" + wrongKeyHmac;
}
}
*위의 코드는 Spring boot 환경에서 thymeleaf를 이용.
// 출력 결과
hmac = 5Y++//KRhZHo+zZ/iTyjAefvxYlAhDoLG12+cByv+D/44Bx6J0/c5M0PycU26Hxabxyci8JkSABMe+jJ3FzlPA==
hmac2 = 5Y++//KRhZHo+zZ/iTyjAefvxYlAhDoLG12+cByv+D/44Bx6J0/c5M0PycU26Hxabxyci8JkSABMe+jJ3FzlPA==
forseryHmac = oMvE4EKMxaxe47ktc4cvAbzmWyciE2vCBV5G/Ju1eL0ZqNx4tgm3KNLfZPU3Rgv0Mse+npSB5fXSzbBQh9WRkQ==
wrongKeyHmac = vRtm5BEPNZNMz0DGyKkHWiWaZkmqkJOi/dfJB512/JPKM6cbeFwZQ7n54WLhJ2YNfKCa3ClqgBIdrJOm2AK8Ig==
'회고록(TIL&WIL)' 카테고리의 다른 글
TIL 2023.06.19 전문통신(Fixed Length Format) (0) | 2023.06.19 |
---|---|
JavaScript, jQuery 정리 (0) | 2023.05.01 |
TIL 2023.03.22 Spring Security, React-Redux, Scheduling (0) | 2023.03.22 |
2023.03.20~2023.03.21 SVN - Jenkins Windows 로컬 서버 CI/CD (0) | 2023.03.21 |
TIL 2023.03.21 암호화, JWT, Spring Security (0) | 2023.03.21 |