1. 개요
SHA(Secure Hash Algorithm)는 널리 사용되는 암호화 해시 함수 중 하나입니다. 암호화 해시를 사용하여 텍스트 또는 데이터 파일에 대한 서명을 만들 수 있습니다. 이 사용방법(예제)에서는 다양한 Java 라이브러리를 사용하여 SHA-256 및 SHA3-256 해싱 작업을 수행하는 방법을 살펴보겠습니다.
SHA-256 알고리즘은 거의 고유 고정 사이즈 256 비트 (32 바이트)의 해시를 생성한다. 이것은 단방향 함수이므로 결과를 원래 값으로 다시 해독할 수 없습니다.
현재 SHA-2 해싱은 암호화 분야에서 가장 안전한 해싱 알고리즘으로 평가받고 있어 널리 사용되고 있다.
SHA-3 은 SHA-2 이후의 최신 Security 해싱 표준입니다. SHA-2와 비교할 때 SHA-3은 고유한 단방향 해시를 생성하는 다른 접근 방식을 제공하며 일부 하드웨어 구현에서는 훨씬 더 빠를 수 있습니다. SHA-256과 유사하게 SHA3-256은 SHA-3의 256비트 고정 길이 알고리즘입니다.
NIST 는 2015년에 SHA-3를 출시했기 때문에 당분간 SHA-2만큼 SHA-3 라이브러리가 많지 않습니다. JDK 9가 되어서야 SHA-3 알고리즘을 기본 제공 기본 제공자에서 사용할 수 있었습니다.
이제 SHA-256부터 시작하겠습니다.
2. 자바의 MessageDigest 클래스
Java는 SHA-256 해싱을 위해 내장된 MessageDigest 클래스를 제공합니다 .
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
그러나 여기에서 16진수로 해시된 값을 얻으려면 사용자 지정 바이트를 16진수로 변환하는 변환기를 사용해야 합니다.
private static String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder(2 * hash.length);
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
우리는 MessageDigest가 스레드로부터 안전하지 않다는 것을 알아야 합니다 . 결과적으로 모든 스레드에 대해 새 인스턴스를 사용해야 합니다.
3. 구아바 도서관
Google Guava 라이브러리는 해싱을 위한 유틸리티 클래스도 제공합니다.
먼저 의존성을 정의해 보겠습니다.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
이제 Guava를 사용하여 문자열을 해시하는 방법은 다음과 같습니다.
String sha256hex = Hashing.sha256()
.hashString(originalString, StandardCharsets.UTF_8)
.toString();
4. 아파치 커먼즈 코덱
마찬가지로 Apache Commons 코덱도 사용할 수 있습니다.
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
다음 은 SHA-256 해싱을 지원하는 DigestUtils 라는 유틸리티 클래스입니다 .
String sha256hex = DigestUtils.sha256Hex(originalString);
5. 바운시 캐슬 라이브러리
5.1. 메이븐 의존성
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
5.2. Bouncy Castle 라이브러리를 사용한 해싱
Bouncy Castle API는 16진수 데이터를 바이트로 변환하고 다시 변환하기 위한 유틸리티 클래스를 제공합니다.
그러나 먼저 내장 Java API를 사용하여 다이제스트를 채워야 합니다.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha256hex = new String(Hex.encode(hash));
6. SHA3-256
이제 SHA3-256을 계속 사용하겠습니다. Java의 SHA3-256 해싱은 SHA-256과 크게 다르지 않습니다.
6.1. Java의 MessageDigest 클래스
JDK 9부터 내장 SHA3-256 알고리즘을 간단히 사용할 수 있습니다.
final MessageDigest digest = MessageDigest.getInstance("SHA3-256");
final byte[] hashbytes = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(hashbytes);
6.2. Apache Commons 코덱
Apache Commons 코덱은 MessageDigest 클래스에 편리한 DigestUtils 래퍼를 제공합니다 . 이 라이브러리는 버전 이후 SHA3-256를 지원하기 시작했다 1.11 , 그리고 9 + JDK가 필요 뿐만 아니라 :
String sha3Hex = new DigestUtils("SHA3-256").digestAsHex(originalString);
6.3. 케칵-256
Keccak-256은 또 다른 인기 있는 SHA3-256 해싱 알고리즘입니다. 현재 표준 SHA3-256의 대안으로 사용됩니다. Keccak-256은 표준 SHA3-256과 동일한 Security 수준을 제공하며 패딩 규칙만 SHA3-256과 다릅니다. Monero 와 같은 여러 블록체인 프로젝트에서 사용되었습니다 .
다시 말하지만, Keccak-256 해싱을 사용하려면 Bouncy Castle Library를 가져와야 합니다.
Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance("Keccak-256");
final byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(encodedhash);
Bouncy Castle API를 사용하여 해싱을 수행할 수도 있습니다.
Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = new String(Hex.encode(hashbytes));
7. 결론
이 빠른 기사에서는 내장 라이브러리와 타사 라이브러리를 모두 사용하여 Java에서 SHA-256 및 SHA3-256 해싱을 구현하는 몇 가지 방법을 살펴보았습니다.
위 예제의 소스 코드는 GitHub 프로젝트 에서 찾을 수 있습니다 .