회원가입시 유저의 비밀번호를 단방향으로 암호화하기 위해 "SHA256 알고리즘"을 선택
SHA256 기본 구조 및 salt 사용 안내
-> https://cocoon1787.tistory.com/832
SHA256 검증 사이트
-> https://coding.tools/kr/sha256
SHA256에 사용되는 MessageDigest 클래스 설명
-> https://ktko.tistory.com/entry/MessageDigest%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9E%90%EB%B0%94%EC%9D%98-Hash-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
바이트 스트림을 32bit로 변환하여 음수를 처리하는 방법
-> https://vmpo.tistory.com/111
public class SHA256 {
public SHA256() {
}
// 0)
public static String createSalt(String plainText) throws NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte [] bytes = new byte[16];
random.nextBytes(bytes);
//SALT 생성
String salt = new String(Base64.getEncoder().encode(bytes));
//System.out.println("{SHA256.Class} salt : " + salt);
return salt;
}
public static String encrypt(String plainText, String salt) {
try {
// 1)
MessageDigest md = MessageDigest.getInstance("SHA-256");
String rawAndSalt = plainText + salt;
//System.out.println("{SHA256.Class} rawAndSalt : " + rawAndSalt);
// 2)
md.update(rawAndSalt.getBytes());
// 3)
byte[] byteData = md.digest(); // 1byte = 8bit
// 4)
StringBuffer hexString = new StringBuffer();
for(int i = 0; i < byteData.length; ++i) {
String hex = Integer.toHexString(255 & byteData[i]);
if (hex.length() == 1) {
hexString.append('0');// 각 byteData당 두 자리 수 16진수로 변환
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception var7) {
var7.printStackTrace();
throw new RuntimeException();
}
}
}
PlainText -> SHA256(Hash Algorithm) -> CipherText
형태의 단방향 암호화를 진행하고, 암호화 키가 존재하지 않기 때문에, 복호화도 불가능하다.
ex)
-1 & 0xFF(255)
(0xFF) 0000 0000 0000 0000 0000 0000 1111 1111
(AND연산) &
(-1) 1111 1111 1111 1111 1111 1111 1111 1111
|---------------------------------------------------------------|
(결과) = 0000 0000 0000 0000 0000 0000 1111 1111
서버 로그인 서비스 API의 일부 코드
1) DB에 저장된 Salt 조회,
2) 사용자가 입력한 PlainText를 Salt와 같이 암호화 후,
3) DB저장 비밀번호와 비교하는 순서
1-1) 회원가입 요청
1-2) 서버 로그 확인
1-3) DB저장 정보 확인
2-1) 로그인 요청
2-2) 서버 로그 확인: DB와 똑같은 비밀번호로 암호화된 CipherText가 출력됨