리눅스는 새로운 암호가 이전 암호와 비슷하다는 것을 어떻게 알 수 있습니까?


145

여러 번 Linux 시스템에서 사용자 비밀번호를 변경하려고 시도했으며 새 비밀번호가 이전 비밀번호와 비슷할 때 OS가 너무 비슷하다고 불평했습니다.

나는 항상 궁금했다. 시스템은 이것을 어떻게 아는가? 암호가 해시로 저장되었다고 생각했습니다. 이것은 시스템이 유사성을 위해 새 비밀번호를 비교할 수있을 때 이전 비밀번호가 실제로 일반 텍스트로 저장됨을 의미합니까?


30
첫 번째 : 일반 텍스트? 아니. (!)가 저장되면 해시를 저장하고 해시를 비교하십시오. Linux에서는 새 비밀번호로 현재 비밀번호를 확인합니다. BOTH는 비밀번호를 변경할 때 사용자가 제공합니다.
Rinzwind

42
@Rinzwind 그러나 하나의 문자 차이로 인해 완전히 다른 해시가 발생하기 때문에 해시를 비교하는 것은 효과가 없습니다.
slhck

17
참조 합니까 페이스 북 스토어 일반 텍스트 암호를? 이전 비밀번호의 해시와 새 비밀번호의 일반 텍스트 (기존의 일반 텍스트 없음)만으로 유사성을 감지하는 다른 방법 은 정보 보안관한 것 입니다.
Bob

21
실제로 해시 된 이전 비밀번호와 일반 텍스트 새 비밀번호의 유사성을 테스트 할 수 있습니다. 새 비밀번호와 유사한 비밀번호 목록을 생성하고 모두 해시 한 다음 결과 해시를 이전 비밀번호 해시와 비교하면됩니다. 일치하면 비슷합니다.
BWG

2
@BWG : 이것은 약간 단순화 된 것입니다. 현재 해싱 체계는 해시에 소금을 뿌립니다. 먼저 이전 암호 해시에서 소금을 추출하여 새 소금과 비슷한 암호에 해당 소금을 사용해야합니다. (나는 API가 특정 소금을 강요하는 방법을 노출시키지 않을 수 있기 때문에 이것을 지적하고있다.)
Ulrich Schwarz

답변:


156

를 사용할 때 이전 비밀번호 새 비밀번호를 모두 제공해야하므로 passwd드라이브의 어딘가에 비밀번호 를 쓰지 않고도 메모리에서 일반 텍스트로 쉽게 비교할 수 있습니다.

실제로 비밀번호는 마지막으로 저장 될 때 해시되지만 비밀번호가 입력 될 때까지 비밀번호를 입력하는 도구는 STDIN에서 읽는 동안 다른 프로그램이 키보드에 입력 한 항목에 액세스 할 수있는 것처럼 비밀번호에 직접 액세스 할 수 있습니다.

이것은 도구 의 배경에서 사용되는 PAM 시스템 의 기능입니다 passwd. PAM은 최신 Linux 배포판에서 사용됩니다.

보다 구체적으로, pam_cracklib몇 가지 약점을 기반으로 암호를 거부하여 매우 취약하게 만드는 PAM 용 모듈입니다.

안전하지 않은 것으로 간주 될 수있는 너무 유사한 암호는 아닙니다. 소스 코드는 암호가 회문 또는 무엇 편집 거리가 두 단어 사이인지 등을 확인할 수 있습니다 무엇의 다양한 사례를 가지고 있습니다. 아이디어는 사전 공격에 대해 암호를 더 잘 보호하는 것입니다.

참조 맨 페이지를.pam_cracklib


당신의 설명이 나의 대답에보고 된 논증과 "어떻게"맞는지에 대한 아이디어가 있습니까? 호스트가 PAM을 인식 하지 못하는 경우 "passwd"응용 프로그램에서 수행하는 두 가지 접근 방식이 있습니까? 추신 : 비평가는 전혀 없습니다. 나는 단지 궁금합니다 (PAM, BTW는 첫 번째 추측이었습니다 ... 소스 코드를 잡기 직전에).
Damiano Verzulli 2014

27
마지막 4 개 중 동일하거나 유사한 암호를 사용한 경우 경고하는 회사 암호 규칙이 더 혼란 스럽습니다.
Nick T

4
@ NickT 어떻게 (필요하게) 혼란 스럽습니까? 마지막 4 개의 해시를 저장 한 다음이 질문과 같은 방식으로 제안 된 새로운 해시를 비교할 수 없었습니까?
neminem

1
@neminem "... 또는 이와 유사한"
Nick T

1
@NickT Ah,이 특정 경우에 사용자는 저장된 해시보다는 암호를 변경하기 위해 사용자가 입력 한 "오래된 암호"와 비교하기 때문에 충분합니다. 그럼에도 불구 하고 실제로 간단한 변경 사항 (한 문자 대체, 한 문자 추가 / 제거 등)을 확인하기 위해 주석에 게시 된 BWG 방법을 가정 할 있습니다.
neminem

46

적어도 우분투에서 "너무 비슷한"메시지가 나왔습니다 언제 : "... 문자의 절반 이상이 다른 문자입니다 ..." (자세한 내용은 아래 참조). @slhck 답변에 명확하게 설명 된 PAM 지원 덕분에.

PAM을 사용하지 않는 다른 플랫폼의 경우 다음과 같은 경우 "너무 유사"메시지가 나타납니다. "... 문자의 절반 이상이 다른 문자입니다 ..." (자세한 내용은 아래 참조)

이 문장을 직접 확인하기 위해 소스 코드를 확인할 수 있습니다. 방법은 다음과 같습니다.

"passwd"프로그램은 passwd 패키지에 포함되어 있습니다 :

verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd

우리는 오픈 소스 기술을 다루면서 소스 코드에 제한없이 액세스 할 수 있습니다. 그것을 얻는 것은 다음과 같이 간단합니다.

verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd

나중에 관련 코드 조각을 쉽게 찾을 수 있습니다.

verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c:     msg = _("too similar");

"obscure.c"에 대한 빠른 검사는 이것을 제공합니다 (관련 코드 조각 만 잘라 붙여 넣습니다).

static const char *password_check (
    const char *old,
    const char *new,
    const struct passwd *pwdp)
{
    const char *msg = NULL;
    char *oldmono, *newmono, *wrapped;

    if (strcmp (new, old) == 0) {
            return _("no change");
    }
    [...]
    if (palindrome (oldmono, newmono)) {
            msg = _("a palindrome");
    } else if (strcmp (oldmono, newmono) == 0) {
            msg = _("case changes only");
    } else if (similar (oldmono, newmono)) {
            msg = _("too similar");
    } else if (simple (old, new)) {
            msg = _("too simple");
    } else if (strstr (wrapped, newmono) != NULL) {
            msg = _("rotated");
    } else {
    }
    [...]
    return msg;
}

따라서, 우리는 이전과 새로운 검사가 둘 다 유사한 경우에 유사한 "유사한"기능이 있다는 것을 알고 있습니다. 스 니펫은 다음과 같습니다.

/*
 * more than half of the characters are different ones.
 */
static bool similar (const char *old, const char *new)
{
    int i, j;

    /*
     * XXX - sometimes this fails when changing from a simple password
     * to a really long one (MD5).  For now, I just return success if
     * the new password is long enough.  Please feel free to suggest
     * something better...  --marekm
     */
    if (strlen (new) >= 8) {
            return false;
    }

    for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
            if (strchr (new, old[i]) != NULL) {
                    j++;
            }
    }

    if (i >= j * 2) {
            return false;
    }

    return true;
}

C 코드를 검토하지 않았습니다. 함수 정의 직전에 주석을 신뢰하는 것으로 제한했습니다 :-)


PAM과 NON-PAM 인식 플랫폼의 차이점은 다음과 같은 구조의 "obscure.c"파일에 정의되어 있습니다.

#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else                           /* !USE_PAM */
extern int errno;               /* warning: ANSI C forbids an empty source file */
#endif                          /* !USE_PAM */

9
이것은 암호가 해시 될 때 이전 암호와 비교할 수있는 방법에 대한 질문에 직접 대답하지 않는 긴 대답입니다.
jamesdlin

10
@jamesdlin : 원래의 질문에 Rinzwind 코멘트에 명시된 바와 같이 해시가 않습니다 NOT 이 문제에 어떤 역할을 : 당신이 암호를 변경하려면 "passwd에"명령을 실행할 때, 당신은 "이전"과 "새로운"암호를 모두 제공 할 필요가 있습니다. 따라서 "passwd"코드는 한 번에 두 암호를 비교 / 확인하는 데 전혀 문제가 없습니다 (명확한 형태로, 전혀 해시되지 않음).
Damiano Verzulli

3
@DamianoVerzulli 그럼에도 불구하고 이것은 실제로 문제를 해결하지 못합니다. 문제는 "두 개의 문자열이 비슷한지를 알리기 위해 어떤 C 코드를 사용 하는가"가 아니 었습니다. 암호와 다른 암호는 동일합니다. 암호 에 대한 흥미로운 점은 평범한 텍스트로 저장되지 않으며 질문이 묻는 것입니다. 이것은 "어떤 기준이 사용되고 C에서 어떻게 수행되는지"에 대한 답변이지만 "어떤 기준"과 "C에서 어떻게해야합니까?"에 대해서는 너무 길다. SU 질문이 아니라 SO 질문이다.
cpast

7
@DamianoVerzulli 그리고 passwd오래된 암호와 새 암호 를 요구 한다는 사실이 입니다. 이 답변의 나머지 부분은 관련이 없습니다.
jamesdlin

3
+1과 관련성이 높고 흥미로운 답변! 암호를 비교하는 실제 코드는 실제로 평문에서 작동하며 예상대로 해시가 아니라는 것을 알면 좋습니다.
nico

36

대답은 생각보다 훨씬 간단합니다. 실제로 트릭을 설명하면 사라지기 때문에 거의 마법으로 자격이 있습니다.

$ passwd
Current Password:
New Password:
Repeat New Password:

Password changed successfully

새 비밀번호가 비슷하다는 것을 알고 있습니다. 바로 이전 비밀번호를 입력했기 때문입니다.


2
"... 또는 사탕"
Nick T

1
바보 토끼, trix는 아이들을위한 것입니다!
iAdjunct

1
설명하지 않은 것은 과거 n 개의 비밀번호를 알고있을 때입니다.
Juha Untinen

3
@ Juha Untinen : 사실이지만 마지막 N 해시를 기억하면 처리 할 수 ​​있습니다. "N 번째 암호와 동일"을 잡는 것은 쉽지만 " N 번째 암호 와 유사 "하기는 어렵습니다. 내가 아는 한,이 시스템은 마지막 암호와의 유사성을 확인하고 마지막 N과의 유사성을 검사합니다. 마지막 N과의 유사성을 검사하는 경우 ... 이것은 정말 흥미로운 트릭입니다! 나는 그들이 어떻게 할 것인지 전혀 모른다.
Cort Ammon

7

다른 답변은 옳지 만 이전 암호를 제공하지 않아도 작동 할 수 있습니다.

실제로, 제공 한 새 비밀번호와 유사한 비밀번호를 생성하여 해시 한 다음이 해시 중 하나가 이전 비밀번호와 일치하는지 확인할 수 있습니다. 이 경우 새 비밀번호는 이전 비밀번호와 비슷한 것으로 판단됩니다! :)


2
이것이 실제로이 위업을 달성하기위한 수단이지만 (많은 웹 사이트에서 사용됨),이 경우에는 일어나지 않습니다.
Brian S

깔끔한 트릭입니다! 조금 더 계산 집약적이지만 영리합니다!
Cort Ammon

의미있는 점검을 수행하거나 외부 리소스에 연결하기 위해 생성해야하는 유사한 암호의 수를 최소한 추정해야합니다. 그렇지 않으면 이것은 가능한 대안에 대한 아이디어 일 뿐이며 확실한 답이 아닙니다.
하이드

@hyde는 누군가가 생각할 수있는 기준에 따라 다릅니다. 나를 위해 최대 3 자 추가 / 제거 / 수정 된 경우 암호는 비슷합니다. 따라서 모든 문자에 대해 62 개의 해시 (그리고 영숫자 만 사용하는 경우)와 암호 길이 ( n) 의 3을 3으로 조합 62 * (n!)/(6 * (n - 3)!)하여 12 자 길이 암호의 경우 13540입니다. 그러나 누군가 다른 것에 대해 생각하면 방정식이 쓸모가 없습니다. 왜 귀찮습니까?
Killah

멍청한 대답이지만 그럼에도 통찰력. 왜 바보 야? 1. 상상할 수없는 수의 해시를 생성해야합니다. 2. 이러한 설정은 원래 비밀번호의 보안을 약화시킵니다. 누군가가 단 하나의 해시가 아닌 모든 유사한 암호의 해시를 얻은 경우 암호를 해독하기가 훨씬 쉽습니다.
Rok Kralj

5

암호 내역이라는 한 가지 측면은 다루지 않았습니다. 일부 시스템은이를 지원합니다. 이를 위해 비밀번호 기록을 유지하고 현재 비밀번호로 암호화합니다. 비밀번호를 변경하면 "이전"비밀번호를 사용하여 목록을 해독하고 확인합니다. 그리고 새 암호를 설정하면 새 암호에서 파생 된 키로 암호화 된 목록 (다시)이 저장됩니다.

이것이 remember=NPAM에서 작동 하는 방식입니다 (에 저장 됨 /etc/security/opasswd). 그러나 Windows 및 기타 Unix 공급 업체도 비슷한 기능을 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.