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


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.