(비밀번호 암호화를 한다고 생각했지만 이번 공부를 통해 정확히는 비밀번호 문자열을 해싱하는것이었다.)
비밀번호가 유출되더라도 복호화 하지 못하여 사용자의 비밀번호를 획득하지 못하게 하기 위해
보통 회원의 비밀번호를 저장할때 단방향 해시함수를 적용한 값을 DB에 저장한다. 단방향 해시 함수의 종류와 이러한 방법이 안전한 방법인지 알아보고자 한다.
💡 digest The message digest produced by the Digest/Hash function is Base64 encoded. 해시에 의해 암호화된 데이터해시 함수를 통해 원본 메세지를 암호화 하는것을 뜻한다. 원본 메세지를 알면 암호화는 쉽지만 암호화된 원본 메세지를 원본 메세지로 구할 수 없어 단방향이라고 표현한다.
| MD5(Message Digest) | SHA-1 | SHA-256 | SHA-512 |
|---|---|---|---|
| 입력데이터의 길이에 상관없이 256비트, 512비트 암호화된 문자열로 전달 | 32bit 텍스트를 256bit의 hash값으로 암호화 | • 64bit 텍스트를 512bit의 hash값으로 암호화 |
• SHA256에 비해 더 많은 비트를 사용하여 입력 데이터에 다양한 속성을 반영할 수 있다.
• SHA256에 비해 더 많은 비트를 사용하여 성능이 좋지 않을 수 있다. |
public static void main(String[] args) {
String password = "testPassword";
String encryptedPassword = null;
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(password.getBytes());
byte[] bytes = m.digest();
StringBuilder s = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
s.append(Integer.toString((bytes[i] & 0xff)+ 0x100, 16).substring(1));
}
encryptedPassword = s.toString();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("encrypted password : "+ encryptedPassword);
System.out.println(encryptedPassword.length());//32
}
hashing은 빠른 검색을 위해 설계된것 이므로 임의의 문자열에 hashing 알고리즘을 적용하여 빠르게 원본 문자열을 파악할 수 있다.

솔트의 길이는 32바이트 이상이어야 비밀번호와 솔트값을 추측하기 어렵다.
다이제스트를 생성할 때 salting과 key stretching을 반복적으로 하여 보안의 강도를 높인 라이브러리다.
spring-security에서도 이러한 라이브러리를 활용한 기능을 제공한다.
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/crypto.html#spring-security-crypto-passwordencoders
하드웨어 성능이 높아짐에 따라 기본 hashing 알고리즘만으로 비밀번호 해싱은 보안성 좋지 않기에 salt값(32비트 이상)의 값을 추가하여 해싱하거나, 보안성을 높인 Adaptive Key Derivation Functions를 사용하는것이 권장된다.
[참고]
https://www.javatpoint.com/how-to-encrypt-password-in-java
https://hackid.tistory.com/m/10
https://d2.naver.com/helloworld/318732
https://www.ibm.com/docs/en/app-connect-pro/7.5.3?topic=reference-digesthash-function
정보가 많아서 도움이 많이 됐습니다.