SHA-256은 SHA(Secure Hash Algorithm) 단방향 알고리즘의 한 종류로, 해시 값을 이용한 암호화 방식 중 하나이다. 256비트로 구성되며 64자리 문자열을 반환한다.
단방향이란 암호화는 가능하나 복호화가 불가능한 것을 의미한다.(반대는 양방향 : 암호화와 복호화 둘 다 가능)
예를 들어, "ABC"라는 값을 SHA-256 알고리즘을 적용하면 "4d35adf24fe634..."와 같은 64자리의 문자열을 반환한다. 해시 값은 한 글자 차이라도 천지 차이로 달라지기 때문에 암호화된 문자열로 원래 문자열을 절대 유추할 수 없다.
보안상의 이유로 DB에 사용자 비밀번호를 직접적으로 넣기보다는 SHA-256 알고리즘을 적용한 후 insert한다. 로그인 시에는 사용자가 입력한 비밀번호에 SHA-256 알고리즘을 적용하고, 입력된 아이디로 DB에 등록된 암호화 비밀번호를 찾아 비교하여 로그인 로직을 처리한다.
사용자 입력 비밀번호을 SHA-256 암호화 == 이미 암호화하여 저장된 비밀번호(사용자 입력 아이디로 레코드 검색)
하지만!! 레인보우 테이블이라는게 생기고, 해커가 암호화된 데이터를 유추할 수 있게 되었다.
레인보우 테이블이란?
해시 함수(MD5, SHA-1, SHA-2 등)을 사용하여 만들어낼 수 있는 값들을 왕창 저장한 표이다
레인보우 테이블의 약점은 원본 문자열이 길고 복잡할수록 테이블에 존재할 가능성이 낮아진다. 이러한 약점을 이용하 원본 문자열에 무작위 문자열(salt)를 합치고, SHA-256 알고리즘을 적용하는 것이다. 그럼 원본 문자열 자체가 더욱 길고 복잡해질테니 레인보우 테이블에 존재하지 않을 가능성이 높아진다.
로그인 시, 사용자가 입력한 아이디로 조회한 레코드에 salt 값을 찾고 입력한 비밀번호에 합친다. 그 후 레코드에 등록된 비밀번호와 비교하면 된다.
사용자 입력 비밀번호을 SHA-256 암호화 + 무작위 문자열(salt) == 이미 암호화하여 저장된 비밀번호
package com.pmp4.amoimproject.common;
import org.springframework.stereotype.Component;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@Component
public class Encrypt {
// 무작위 문자열 Salt
public String getSalt() {
//1. Random, salt 생성
SecureRandom sr = new SecureRandom();
byte[] salt = new byte[20];
//2. 난수 생성
sr.nextBytes(salt);
//3. byte To String (10진수 문자열로 변경)
StringBuffer sb = new StringBuffer();
for(byte b : salt) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
// SHA-256 알고리즘 적용
public String getEncrypt(String pwd, String salt) {
String result = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
// System.out.println("PWD + SALT 적용 전 : " + pwd + salt);
md.update((pwd + salt).getBytes());
byte[] pwdSalt = md.digest();
StringBuffer sb = new StringBuffer();
for(byte b : pwdSalt) {
sb.append(String.format("%02x", b));
}
result = sb.toString();
// System.out.println("PWD + SALT 적용 후 : " + result);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
return result;
}
}
"testtest123" 이라는 비밀번호를 입력한 후, 암호화를 하면 저렇게 반환된다.
JAVA에서 SHA-256 알고리즘을 위해 제공하는 패키지는
java.security이다.
감사합니다 큰 도움되었습니다