Linux(Ubuntu)의 /etc/shadow에 저장된 해시(ASCII) 코드에 대해 혼란스럽습니다.
사례를 가정하고 비밀번호를 다음과 같이 설정하세요.'시험', 소금은'Zem197T4'.
다음 명령을 실행하여,
$ mkpasswd -m SHA-512 test Zem197T4
긴 ASCII 문자 문자열을 생성합니다(실제로 Linux가 이를 /etc/shadow에 저장하는 방식입니다).
$6$Zem197T4$oCUr0iMuvRJnMqk3FFi72KWuLAcKU.ydjfMvuXAHgpzNtijJFrGv80tifR1ySJWsb4sdPJqxzCLwUFkX6FKVZ0
온라인 SHA-512 생성기를 사용하는 경우(예:http://www.insidepro.com/hashes.php?lang=eng), 생성되는 내용은 아래와 같이 16진수 코드입니다.
옵션 1) 비밀번호 + 솔트
8d4b73598280019ef818e44eb4493c661b871bf758663d52907c762f649fe3355f698ccabb3b0c59e44f1f6db06ef4690c16a2682382617c6121925082613fe2
옵션 2) 소금+비밀번호
b0197333c018b3b26856473296fcb8637c4f58ab7f4ee2d6868919162fa6a61c8ba93824019aa158e62ccf611c829026b168fc4bf90b2e6b63c0f617198006c2
나는 이 16진수 코드가 mkpasswd에 의해 생성된 ASCII 코드와 "동일"해야 한다고 생각합니다. 그러나 그들은 어떻게 관련되어 있습니까?
누군가가 나를 깨달을 수 있기를 바랍니다.
답변1
Ubuntu/Debian에서는 mkpasswd
패키지의 일부입니다.누구인가?그리고 여기에 구현된 것은 mkpasswd.c
실제로 crypt()
glibc에 선언된 함수에 대한 복잡한 래퍼 일 뿐입니다 unistd.h
. crypt()는 비밀번호와 솔트라는 두 가지 매개변수를 사용합니다. 이 예에서 비밀번호는 "test"이고 솔트 접두사는 SHA-512 해시 "$6$"입니다(참조:SHA 암호화) 따라서 "$6$Zem197T4"가 crypt()에 전달됩니다.
-R
아마도 옵션 에 따라 mkpasswd
라운드 수가 결정된다는 사실을 눈치챘을 것입니다 . 문서에서 기본값은 5000라운드임을 알 수 있습니다. 이는 왜 결과가 솔트와 비밀번호의 단순한 연결과 같지 않고 한 번만 해시되지 않는지에 대한 첫 번째 힌트입니다. 실제로 통과하면 -R 5000
동일한 결과를 얻게 됩니다. 이 경우 "$6$rounds=5000$Zem197T4"가 crypt()에 전달되고 glibc(Debian/Ubuntu의 경우 libc) 구현은 여기에서 메서드와 라운드 번호를 추출합니다.
crypt() 내부에서 일어나는 일은 단일 해시를 계산하는 것보다 더 복잡하며 결과는 Base64로 인코딩됩니다. 그렇기 때문에 표시되는 결과에는 SHA-512 해시의 일반적인 16진수 문자열에 있는 [0-9a-f]뿐만 아니라 마지막 "$" 뒤의 모든 유형의 문자가 포함됩니다. 알고리즘은 이미 언급한 부분에 자세히 설명되어 있습니다.SHA 암호화문서.
답변2
솔트된 비밀번호를 사용하는 전체 아이디어는 동일한 비밀번호에 대해 해시를 생성할 때마다 다른 결과를 얻는다는 것입니다. 이는 레인보우 테이블의 문제를 방지하기 위한 것입니다.
귀하의 사용자 중 한 명이 123456과 같은 취약한 비밀번호를 사용하고 귀하의 /etc/shadow가 노출된다고 가정해 보십시오. 이제 사악한 해커가 해야 할 일은 레인보우 테이블을 사용하여 취약한 비밀번호를 찾아 다른 곳에서 다시 사용하는 것뿐입니다.