목차
0. HMAC 암호화 들어가기 전에
0.1. MAC(Message Authentication Code)란?
- 메시지의 무결성(integrity)과 메시지 인증(authentication) 목적으로 사용합니다.
- 메시지가 내가 원하는 사람으로부터 왔는지 판단할 수 있게 해 줌(KEY 이용)
- 공유된 키를 가지고 메시지 해쉬값(MAC)을 만들어 냅니다.
- 메시지 변조와 위장을 막을 수 있습니다.
EX1. ) A가 B에게 보내는 메시지를 C가 중간에서 변조합니다.
EX2. ) C가 A인척 위장을 하고 B에게 메시지를 보냅니다.
0.2. HMAC(Keyed-Hash Message Authentication Code)란?
- 해시 함수를 이용해서 메시지 인증 코드를 구성하는 방법을 HMAC 이라 합니다.
- 암호화 해시 함수와 기밀 암호화 키를 수반하는 특정한 유형의 메시지 인증 코드(MAC)입니다.
- 원본 메시지가 변하면 그 해시값도 변하는 해싱(Hashing)의 특징을 활용하여 메시지의 변조 여부를 확인(인증) 하여 무결성과 기밀성을 제공하는 기술입니다.
- HMAC = Hash(Message, Key) + Message
- HMAC-X: X는 사용이 되는 해시 함수(예: HMAC-SHA256 또는 HMAC-SHA3-256)를 의미합니다.
- HMAC의 암호화 등급은 그 기반이 되는 해시 함수의 암호화 등급, 해시 출력의 크기, 키의 크기와 품질에 따라집니다.
- HMAC는 IPsec, SSH, TLS 프로토콜, 그리고 JSON 웹 토큰에 사용됩니다.
- 메시지 무결성, 인증(메시지 송신자의 검증), 부인방지
0.3. 준비하기
- 암호화에 Java 기본 라이브러리(javax.crypto.Mac, javax.crypto.spec.SecretKeySpec)를 사용합니다.
- 필자의 자바 환경: java-1.8.0-openjdk-1.8.0.242
- 암호화 한 값을 출력(인코딩)을 위해 Apache Commons 라이브러리를 사용합니다(다운로드 필요!).
프로젝트 자바 추가, 변경 및 적용을 모를 경우 아래의 링크를 참조해주세요.
Apache Commons 라이브러리 링크: http://mvnrepository.com/artifact/commons-codec/commons-codec/1.9
프로젝트에 다운로드한 라이브러리 추가하기
1. HMAC + X(Hash) + Hex Encode 암호화
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class HmacShaClass {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
String text = "Hmac Test Text";
String secretKey = "Hmac Key";
System.out.println("암호화 전: " + text);
System.out.println("-------------------------------------------------------");
System.out.println("Hmac-MD5(Hex): " + HmacAndHex(secretKey, text, "HmacMD5"));
System.out.println("Hmac-SHA1(Hex): " + HmacAndHex(secretKey, text, "HmacSHA1"));
System.out.println("Hmac-SHA224(Hex): " + HmacAndHex(secretKey, text, "HmacSHA224"));
System.out.println("Hmac-SHA256(Hex): " + HmacAndHex(secretKey, text, "HmacSHA256"));
System.out.println("Hmac-SHA384(Hex): " + HmacAndHex(secretKey, text, "HmacSHA384"));
System.out.println("Hmac-SHA512(Hex): " + HmacAndHex(secretKey, text, "HmacSHA512"));
System.out.println("-------------------------------------------------------");
}
public static String HmacAndHex(String secret, String data, String Algorithms) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
//1. SecretKeySpec 클래스를 사용한 키 생성
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("utf-8"), Algorithms);
//2. 지정된 MAC 알고리즘을 구현하는 Mac 객체를 작성합니다.
Mac hasher = Mac.getInstance(Algorithms);
//3. 키를 사용해 이 Mac 객체를 초기화
hasher.init(secretKey);
//3. 암호화 하려는 데이터의 바이트의 배열을 처리해 MAC 조작을 종료
byte[] hash = hasher.doFinal(data.getBytes());
//4. Hex Encode to String
return Hex.encodeHexString(hash);
}
}
결과 값
암호화 전: Hmac Test Text
-------------------------------------------------------
Hmac-MD5(Hex): 1d2506fc24c614e9ecc744a91234c493
Hmac-SHA1(Hex): 61efe9fed266a3781e1a75ba3e64579566b21be6
Hmac-SHA224(Hex): 2b837bffcff561b4f00468f65fc9dd54322c1a82eecbe58c18a0edd9
Hmac-SHA256(Hex): ff21b4e6489003180e175e7ae37c218eaa655ebd67053ae96533f7d4673ed93e
Hmac-SHA384(Hex): 1deaf0fe74fb96be3ace67807d1921f0ec53e89a6d4ce87762ddc82abb567af62f4713b3c743773b0e1dd09fe1cd2c2f
Hmac-SHA512(Hex): fc05c569164807c621e6a62ea8acdbea4f450bcf0585f788ae113d1a991ca5ad28f179c2d6f4f1d254445a348d227b6f1c85c1943794bc9347054abd4191ff57
-------------------------------------------------------
2. HMAC + X(Hash) + Base64 Encode 암호화
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class HmacShaClass {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
String text = "Hmac Test Text";
String secretKey = "Hmac Key";
System.out.println("암호화 전: " + text);
System.out.println("-------------------------------------------------------");
System.out.println("Hmac-MD5(Base64): " + HmacAndBase64(secretKey, text, "HmacMD5"));
System.out.println("Hmac-SHA1(Base64): " + HmacAndBase64(secretKey, text, "HmacSHA1"));
System.out.println("Hmac-SHA224(Base64): " + HmacAndBase64(secretKey, text, "HmacSHA224"));
System.out.println("Hmac-SHA256(Base64): " + HmacAndBase64(secretKey, text, "HmacSHA256"));
System.out.println("Hmac-SHA384(Base64): " + HmacAndBase64(secretKey, text, "HmacSHA384"));
System.out.println("Hmac-SHA512(Base64): " + HmacAndBase64(secretKey, text, "HmacSHA512"));
System.out.println("-------------------------------------------------------");
}
public static String HmacAndBase64(String secret, String data, String Algorithms) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
//1. SecretKeySpec 클래스를 사용한 키 생성
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("utf-8"), Algorithms);
//2. 지정된 MAC 알고리즘을 구현하는 Mac 객체를 작성합니다.
Mac hasher = Mac.getInstance(Algorithms);
//3. 키를 사용해 이 Mac 객체를 초기화
hasher.init(secretKey);
//3. 암호화 하려는 데이터의 바이트의 배열을 처리해 MAC 조작을 종료
byte[] hash = hasher.doFinal(data.getBytes());
//4. Base 64 Encode to String
return Base64.encodeBase64String(hash);
}
}
결과 값
암호화 전: Hmac Test Text
-------------------------------------------------------
Hmac-MD5(Base64): HSUG/CTGFOnsx0SpEjTEkw==
Hmac-SHA1(Base64): Ye/p/tJmo3geGnW6PmRXlWayG+Y=
Hmac-SHA224(Base64): K4N7/8/1YbTwBGj2X8ndVDIsGoLuy+WMGKDt2Q==
Hmac-SHA256(Base64): /yG05kiQAxgOF15643whjqplXr1nBTrpZTP31Gc+2T4=
Hmac-SHA384(Base64): Herw/nT7lr46zmeAfRkh8OxT6JptTOh3Yt3IKrtWevYvRxOzx0N3Ow4d0J/hzSwv
Hmac-SHA512(Base64): /AXFaRZIB8Yh5qYuqKzb6k9FC88FhfeIrhE9Gpkcpa0o8XnC1vTx0lREWjSNIntvHIXBlDeUvJNHBUq9QZH/Vw==
-------------------------------------------------------
'Backend > Java' 카테고리의 다른 글
[java] 자바8 함수형 인터페이스 (@FunctionalInterface) (0) | 2021.12.06 |
---|---|
[JAVA] 자바 AES 암호화 하기 (AES-128, AES-192, AES-256) (0) | 2021.08.28 |
[JAVA] 자바 SHA 암호화 하기 (SHA1, SHA2, SHA3) (0) | 2021.08.15 |
[JAVA] 자바 MD5 암호화 (단방향 암호화) (0) | 2021.08.14 |
[JAVA] Hex 인코딩 디코딩 방법 (16 진수) (0) | 2021.08.13 |