▼ Backend/자바 (JAVA)

JAVA | 비밀번호의 암호화 (SHA, SALT)

Valar 2021. 8. 19. 14:56
반응형

▶ SHA(Secure Hash Algorithm)

비밀번호 암호화로 단방향 암호화 기법을 많이 사용하는데 그중에서도 SHA에 대해 알아본다.

 

대분류 중분류
 MD 길이  블록 길이  최대 메시지 길이  대표 알고리즘 
 해쉬 알고리즘
 (Hash Algorithm)
SHA-1  160bit  512bit  2^64-1bit  SHA-1
SHA-2  224bit  512bit  2^64-1bit  SHA-224
SHA-2  256bit  512bit  2^64-1bit  SHA-256
SHA-2  384bit  1024bit  2^128-1bit  SHA-384
SHA-2  512bit  1024bit  2^128-1bit  SHA-512

 

▶ 왜 단방향 암호화를 사용할까?

단순한 이유는 시스템이 사용자의 비밀번호의 원본 데이터를 알아야 할 필요가 없고, (개인정보, 보안상의 이유도 양방향 암호화를 사용하여 비밀번호를 저장하여 사용중에 탈취되었을 때 복호화되어 다른 시스템에서 악용될 수 있는 2차 문제를 사전에 방지하기 위해서이다.

 

▶ 단방향 암호화의 사용

SHA 계열의 해시함수를 통해 사용자의 비밀번호를 해싱하여 나온 해시값을 데이터베이스에 저장해두었다가, 사용자가 로그인 시도를 할 때 입력한 비밀번호를 해싱하여 나온 해시값과 비교하여 검증하게 된다.

 

▶ 문제의 발견

이러한 과정에서 문제가 발생했다. 데이터에 따른 동일한 해시값이 나온다는 것을 이용하여 많은 비밀번호 조합에 대해 해시를 사전에 연산한 후 레인보우 테이블(rainbow table)이라는 곳에 미리 적재해 놓은 후 해시값을 발견하면 색인을 수행해 동일한 해시와 일치하는지 확인하는 것이다.

 

▶ 문제의 해결

문제를 해결하기 위해서 나온 방법 중에 하나는 데이터를 해싱하기 전에 임의의 값(salt)을 붙여서

해싱을 수행하는 것이다. 

 

*임의의 값(salt)을 최소 16글자 길이로 하면 평문 문자열의 복잡성과 길이가 크게 증가한다고 한다.

 

이러한 임의의 값은 파일 시스템 권한으로 보호되는 애플리케이션 구성 파일 또는 HSM(Hardware Security Module)등의 안전한 장소에 보관한다.

 

▶ 해시란?

임의의 크기를 가진 데이터를 고정된 데이터의 크기로 변환시키는 것을 말한다.

 

HashEncryptionUtil.java

 

package com.melon.boot.util;

import java.math.BigInteger;
import java.security.MessageDigest;

public class HashEncryptionUtil {
    public static String encryptSHA256(String password, String salt) throws Exception {
    	if (password != null && salt != null) {
    		// MD2, MD4, MD5, SHA-1, SHA-256, SHA-512
    		MessageDigest md = MessageDigest.getInstance("SHA-256");
    		
    		md.reset();
    		
    		// salt 바이트 데이터를 사용해 다이제스트를 갱신
    		md.update(salt.getBytes()); 
    		
    		// 바이트배열로 해쉬를 반환, 패딩 등의 최종 처리를 행해 해시 계산을 완료
    		byte[] digested = md.digest(password.getBytes()); 	
    		
    		return String.format("%064x", new BigInteger(1, digested));
    	} else {
    		return "";
    	}
    }
}
반응형