안녕하세요. 오늘은 String을 해시 코드로 변환해보겠습니다. 일반적으로 해시는 비밀번호 저장 시에 많이 사용되죠? 이것을 자바에서 어떻게 사용하는지 알아봅시다.
MessageDigest
저희는 java.security
패키지의 `MessageDigest` 클래스를 사용할 겁니다.
var algorithm = "SHA-256";
var md = MessageDigest.getInstance(algorithm);
이렇게 하면 MessageDigest
객체를 얻을 수 있습니다. 사용 가능한 해시 함수 알고리즘은 아래와 같습니다.(공식 문서)
- MD2
- MD5
- SHA-1
- SHA-224
- SHA-256
- SHA-384
- SHA-512
- SHA-512/224
- SHA-512/256
- SHA3-224
- SHA3-256
- SHA3-384
- SHA3-512
문자열을 해시 함수에 적용하기
이제 문자열을 MessageDiagest
를 통해 해시 함수를 적용시켜 봅시다.
var algorithm = "SHA-256";
var md = MessageDigest.getInstance(algorithm);
var inputBytes = "test!@#$1234".getBytes();
var outputBytes = md.digest(inputBytes);
- 적용하고자 하는
String
의byte
배열 가져오기(getBytes
사용) MessageDigest
의digest
함수를 통해 해시된byte
배열 받아오기
byte 배열을 String으로 변환하기
MessageDigest
의 digest
함수는 byte
배열을 반환합니다. 저희가 필요한 건 해시된 String
인데 이를 어떻게 변환해야 할까요?
일반적으로 쓰는 방법은 16진수를 이용하는 것입니다. byte
는 두 개의 16진수로 표현할 수 있습니다.
그렇다면 byte를 16진수로 표현해 봅시다.Integer
클래스에는 toString
이라는 정적 메서드가 있습니다. 그중에 toString(int i, int radix)
함수는 n진수를 정할 수 있습니다. 저는 이 함수를 사용할 겁니다.
var algorithm = "SHA-256";
var md = MessageDigest.getInstance(algorithm);
var inputBytes = "test!@#$1234".getBytes();
var outputBytes = md.digest(inputBytes);
var sb = new StringBuilder();
for (var ob : outputBytes){
// byte를 int로 형변환
int i = (int) ob;
// int를 16진수 String으로 변환
sb.append(Integer.toString(i, 16));
}
System.out.println(sb);
// 결과 : 69-7d3d26-1-4628-26-335a-39-394c372449f-441-57-4d5c-1e-5e-1510-3243-b60774a
실행해 보면 결과에 음수가 붙어서 나오는 것을 볼 수 있습니다. 이렇게 사용해도 문제는 없겠지만, 한번 제거해 봅시다.
byte 배열을 String으로 변환하기 - 음수 제거하기
아래와 같이 코드를 변경하면 됩니다. 자세한 원리는 여기를 참고해 주세요.
var algorithm = "SHA-256";
var md = MessageDigest.getInstance(algorithm);
var inputBytes = "test!@#$1234".getBytes();
var outputBytes = md.digest(inputBytes);
var sb = new StringBuilder();
for (var ob : outputBytes){
int i = ((int) ob & 0xff) + 0x100;
sb.append(Integer.toString(i, 16).substring(1));
}
System.out.println(sb);
// 결과 : 69833d26ffba28dacd5ac7c74c3724490fbc01a9b35ce2a2eb10ce43f560774a
전체 코드
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException {
var algorithm = "SHA-256";
var md = MessageDigest.getInstance(algorithm);
var inputBytes = "test!@#$1234".getBytes();
var outputBytes = md.digest(inputBytes);
var sb = new StringBuilder();
for (var ob : outputBytes){
int i = ((int) ob & 0xff) + 0x100;
sb.append(Integer.toString(i, 16).substring(1));
}
System.out.println(sb);
}
}
'JVM > Java' 카테고리의 다른 글
Java의 동기화(synchronized, wait(), notify()) (0) | 2025.02.03 |
---|---|
Java Virtual Thread 사용하는 방법 (0) | 2025.02.03 |
Java의 Virtual Thread에 대해서(JEP444) (0) | 2025.02.02 |