개발/개발관련

[개발관련] 솔트 없이 일방향 해시 함수 사용 조치

mabb 2023. 12. 21. 17:42
반응형

솔트 없이 일방향 해시 함수를 사용하여 비밀번호를 저장한 사항에 대해 조치해야 할 일이 생겼다.
다음은 솔트 없이 SHA-256 해시 알고리즘을 사용하는 비밀번호(pwd) 변환 java 소스이다.

            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(pwd.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer();

            for (int i = 0; i < hash.length; i++) {
                String hex = Integer.toHexString(0xff & hash[i]);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();


MessageDigest라는 클래스를 사용하는데 여기서 Digest란 단어가 등장한다. 다이제스트는 해시알고리즘으로 변환한 데이터를 뜻한다고 한다. SHA-256 알고리즘으로 변환한 다이제스트의 일반적인 모습은 다음과 같다.

8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918


굉장히 복잡해 보이는 64자리의 문자열이다. 하지만 이것이 'admin'이라는 것을 한 눈에 알 수가 있는데, 그 이유는 저 문자열이 테스트용으로 자주 사용하는 패스워드의 다이제스트여서 눈에 익기 때문이다.그렇다. SHA-256 단방향 해시 알고리즘으로 만든 다이제스트는 길이가 고정일 뿐만 아니라, 원래의 문자가 같으면 항상 같은 다이제스트를 만들어낸다.


(SHA-256 단방향 해시 알고리즘에 대해 잘 설명된 사이트 ↓)

 

SHA256 - 해시넷

SHA-256은 SHA(Secure Hash Algorithm) 알고리즘의 한 종류로서 256비트로 구성되며 64자리 문자열을 반환한다. SHA-256은 미국의 국립표준기술연구소(NIST; National Institute of Standards and Technology)에 의해 공표된

wiki.hash.kr

 

같은 문자열은 같은 다이제스트가 된다라는 점 때문에 보안상 취약점이 발생하게 된다. 아래와 같은 사이트가 있다는 것이 이를 증명한다. 다이제스트를 검색할 경우 원문이 무엇인지 신속하게 알려준다. SHA-256 단방향 해시 알고리즘으로 변환한 다이제스트는 다시 원래의 데이터로 복호화 할 수 없다. 하지만 원문과 다이제스트의 1대1관계로 인하여 축적된 데이터테이블(레인보우 테이블이라고 한다)을 통해서 다이제스트의 원문이 무엇이었는지 알 수가 있는 것이다. 아래의 사이트에서 위의 다이제스트를 검색하면 "admin"이라고 알려준다.

 

CrackStation - Online Password Hash Cracking - MD5, SHA1, Linux, Rainbow Tables, etc.

Free Password Hash Cracker Enter up to 20 non-salted hashes, one per line: Supports: LM, NTLM, md2, md4, md5, md5(md5_hex), md5-half, sha1, sha224, sha256, sha384, sha512, ripeMD160, whirlpool, MySQL 4.1+ (sha1(sha1_bin)), QubesV3.1BackupDefaults How Crack

crackstation.net

 

admin SHA 256 rainbowtable 검색 시 나오는 사이트

 

현재의 비밀번호 인증 로직에서는 사용자가 회원가입 시 입력한 비밀번호에 해시 알고리즘을 적용하여 만든 다이제스트를 데이터베이스에 저장하고, 로그인 시에는 사용자가 입력한 데이터의 다이제스트와 데이터베이스의 다이제스트를 비교하여 비밀번호를 인증한다.

같은 문자열은 같은 다이제스트가 된다 라는 약점을 보완하기 위해 사용할 수 있는 수단이 '솔트'라고 한다. 의미는 간단한데, 소금을 치듯 무작위 난수값을 원문에 더하는 것이다. 솔트가 더해진 비밀번호로 생성한 다이제스트에서 원문을 찾아내기는 훨씬 어려울 것이기 때문에 보안 상 유리하다.

다른 방법으로 생각해볼 수 있는 것은 다이제스트의 다이제스트의 다이제스트를 만드는 것이다. 해시 알고리즘을 여러 번 수행하는 것이다.

이제 솔트 없이 단방향 해시 함수를 사용하여 패스워드를 저장한 것에 대해 다음과 같이 조치를 해 볼 것이다.
솔트를 어렵게 만들거나, 해시 알고리즘 반복 횟수에 변화를 주거나, 두 가지를 조합하면서 단방향 해시알고리즘에 대한 보안을 강화할 수 있을 것 같다.

1.사용자 별 솔트를 데이터베이스에 저장
 1.1.솔트의 발급 시점은 회원가입 시, 비밀번호 변경 시 로 생각해본다.
 1.2.이미 솔트 없이 생성된 계정에 대해 비밀번호 변경을 유도해야 한다. (솔트가 없는 user 는 비밀번호 변경 창 강제 팝업)

2. 사용자 ID에 매칭된 솔트 셀렉트

3. 다이제스트 생성
 3.1. PW에 솔트를 붙이고, (솔트의 1의 자리 숫자/3) 만큼 해시 알고리즘을 반복하여 다이제스트 생성

 

반응형