1. 개요

이 사용방법(예제)에서는 암호 해싱의 중요성에 대해 설명합니다.

우리는 그것이 무엇인지, 왜 중요한지, 그리고 자바에서 그것을 수행하는 몇 가지 안전하고 안전하지 않은 방법에 대해 간단히 살펴볼 것입니다.

2. 해싱이란 무엇입니까?

해싱암호화 해시 함수 로 알려진 수학적 함수를 사용하여 주어진 메시지 에서 문자열 또는 해시 를 생성하는 프로세스입니다 .

여러 해시 기능이 있지만 해싱 암호에 맞게 조정 된 기능은 Security을 유지하기 위해 4 가지 주요 속성을 가져야합니다.

  1. 결정적 이어야합니다 . 동일한 해시 함수로 처리 된 동일한 메시지는 항상  동일한 해시를 생성  해야합니다. 
  2. 되돌릴 수 없습니다  . 해시 에서 메시지 를 생성하는 것은 비현실적입니다. 
  3. 엔트로피 가 높음 : 메시지 를 조금만 변경  하면 매우 다른 해시 가 생성됩니다. 
  4. 그리고 충돌에 저항합니다 . 두 개의 다른  메시지 가 동일한 해시를 생성해서는 안됩니다. 

네 가지 속성을 모두 포함하는 해시 함수는 함께 해시에서 암호를 리버스 엔지니어링하는 데 어려움을 극적으로 증가시키기 때문에 암호 해싱에 대한 강력한 후보입니다.

또한 암호 해싱 기능은 느려 야합니다 . 빠른 알고리즘은 해커가 초당 수십억 개 ( 또는 수조 개 )의 잠재적 암호 를 해싱하고 비교하여 암호를 추측하는 무차별 대입  공격지원 합니다.

이러한 모든 기준을 충족하는 몇 가지 훌륭한 해시 함수는 PBKDF2,  BCrypt  및  SCrypt입니다. 하지만 먼저 오래된 알고리즘과 더 이상 권장되지 않는 이유를 살펴 보겠습니다. 

3. 권장하지 않음 : MD5

첫 번째 해시 함수는 1992 년에 개발 된 MD5 메시지 다이제스트 알고리즘입니다.

Java의  MessageDigest를 사용하면이를 쉽게 계산할 수 있으며 다른 상황에서도 유용 할 수 있습니다.

그러나 지난 몇 년 동안 MD5는  충돌 생성이 계산적으로 쉬워 졌다는 점에서 네 번째 암호 해싱 속성실패한 것으로 밝혀졌습니다 . 게다가 MD5는 빠른 알고리즘이므로 무차별 대입 공격에 대해 쓸모가 없습니다.

이 때문에 MD5는 권장되지 않습니다.

4. 권장하지 않음 : SHA-512

다음으로 1993 년에 SHA-0으로 시작된 제품군 인 Secure Hash Algorithm 제품군의 일부인 SHA-512를 살펴 보겠습니다.

4.1. 왜 SHA-512입니까?

컴퓨터의 성능이 향상되고 새로운 취약점이 발견되면 연구원은 새로운 버전의 SHA를 도출합니다. 최신 버전은 점진적으로 더 긴 길이를 갖거나 때로는 연구원이 새로운 버전의 기본 알고리즘을 게시합니다.

SHA-512는 알고리즘의 3 세대에서 가장 긴 키를 나타냅니다.

하지만 지금은 SHA의 더 안전한 버전이 , SHA-512은 자바로 구현되는 강력한입니다 .

4.2. 자바로 구현

이제 Java에서 SHA-512 해싱 알고리즘을 구현하는 방법을 살펴 보겠습니다.

먼저 소금 의 개념을 이해해야합니다  . 간단히 말해서, 이것은 각각의 새로운 해시에 대해 생성되는 랜덤의 시퀀스입니다 .

이 임의성을 도입함으로써 해시의 엔트로피를 증가시키고 레인보우 테이블 로 알려진 사전 컴파일 된 해시 List으로부터 데이터베이스를 보호합니다 .

새로운 해시 함수는 대략 다음과 같습니다.

salt <- generate-salt;
hash <- salt + ':' + sha512(salt + password)

4.3. 소금 생성

솔트를 소개하기 위해 java.securitySecureRandom  클래스를 사용할 것입니다  .

SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);

그런 다음 MessageDigest  클래스를 사용하여  솔트로 SHA-512  해시 함수 를 구성합니다  .

MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt);

그리고이를 추가하여 이제 다이제스트 메서드를 사용하여 해시 된 암호를 생성 할 수 있습니다 .

byte[] hashedPassword = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));

4.4. 권장되지 않는 이유는 무엇입니까?

소금과 함께 사용하는 경우, SHA-512은 여전히 공정한 옵션입니다 , 하지만 거기 강하고 느린 옵션이 있습니다 .

또한 우리가 다룰 나머지 옵션에는 구성 가능한 강도라는 중요한 기능이 있습니다.

5. PBKDF2, BCrypt 및 SCrypt

PBKDF2, BCrypt 및 SCrypt는 세 가지 권장 알고리즘입니다.

5.1. 권장되는 이유는 무엇입니까?

이들 각각은 느리고 각각 구성 가능한 강도를 갖는 뛰어난 기능을 가지고 있습니다.

이것은 컴퓨터의 강도가 증가함에 따라 입력을 변경하여 알고리즘을 늦출 수 있음을 의미합니다  .

5.2. 자바에서 PBKDF2 구현

이제  솔트는 암호 해싱의 기본 원칙 이므로 PBKDF2에도 솔트가 필요합니다.

SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);

다음으로  PBKDF2WithHmacSHA1  알고리즘을  사용하여 인스턴스화 할 PBEKeySpec  및 SecretKeyFactory 를 생성  합니다.

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

세 번째 매개 변수 ( 65536 )는 사실상 강도 매개 변수입니다. 이 알고리즘이 실행되는 반복 횟수를 나타내므로 해시를 생성하는 데 걸리는 시간이 늘어납니다.

마지막으로 SecretKeyFactory  를 사용하여 해시를 생성 할 수 있습니다  .

byte[] hash = factory.generateSecret(spec).getEncoded();

5.3. Java에서 BCrypt 및 SCrypt 구현

따라서 일부 Java 라이브러리에서 지원하지만 BCrypt 및 SCrypt 지원은 아직 Java와 함께 제공되지 않습니다 .

이러한 라이브러리 중 하나는 Spring Security입니다.

6. 스프링 Security으로 암호 해싱

Java는 기본적으로 PBKDF2 및 SHA 해싱 알고리즘을 모두 지원하지만 BCrypt 및 SCrypt 알고리즘은 지원하지 않습니다.

다행스럽게도 Spring Security는 PasswordEncoder 인터페이스 를 통해 이러한 모든 권장 알고리즘에 대한 지원을  제공합니다.

  • MessageDigestPasswordEncoder  는 MD5 및 SHA-512를 제공합니다.
  • Pbkdf2PasswordEncoder 는 PBKDF2를 제공합니다.
  • BCryptPasswordEncoderBCrypt를  제공하고
  • SCryptPasswordEncoder 는 우리에게 SCrypt를  제공합니다.

PBKDF2, BCrypt 및 SCrypt 용 암호 인코더는 모두 원하는 암호 해시 강도를 구성 할 수 있도록 지원합니다.

Spring Security 기반 애플리케이션이 없어도 이러한 인코더를 직접 사용할 수 있습니다. 또는 Spring Security로 사이트를 보호하는 경우 DSL 또는 의존성 주입을 통해 원하는 암호 인코더를 구성 할 수 있습니다 .

그리고 위의 예와 달리 이러한 암호화 알고리즘은 내부적으로 우리를 위해 솔트를 생성합니다 . 알고리즘은 나중에 암호 유효성 검사에 사용하기 위해 출력 해시 내에 솔트를 저장합니다.

7. 결론

그래서 우리는 암호 해싱에 대해 심층적으로 살펴 보았습니다. 개념과 그 용도를 탐구합니다.

그리고 우리는 Java로 코딩하기 전에 일부 역사적인 해시 함수와 현재 구현 된 일부 함수를 살펴 보았습니다.

마지막으로, Spring Security는 다양한 해시 함수 배열을 구현하는 암호 암호화 클래스와 함께 제공됩니다.

항상 그렇듯이 코드는 GitHub에서 사용할 수 있습니다.