Làm thế nào để Linux biết rằng mật khẩu mới tương tự như mật khẩu trước đó?


145

Một vài lần tôi đã cố gắng thay đổi mật khẩu người dùng trên nhiều máy Linux khác nhau và khi mật khẩu mới giống với mật khẩu cũ, HĐH đã phàn nàn rằng chúng quá giống nhau.

Tôi luôn tự hỏi, làm thế nào để hệ thống biết điều này? Tôi nghĩ rằng mật khẩu được lưu dưới dạng băm. Điều này có nghĩa là khi hệ thống có thể so sánh mật khẩu mới về sự giống nhau thì mật khẩu cũ thực sự được lưu dưới dạng văn bản thuần túy?


30
1 tắt: văn bản đơn giản? Không. Nếu (!) Đã lưu, bạn lưu hàm băm và so sánh giá trị băm. Trong Linux mặc dù nó kiểm tra mật khẩu hiện tại với mật khẩu mới. Cả hai được cung cấp bởi người dùng khi thay đổi mật khẩu.
Rinzwind

42
@Rinzwind Nhưng việc so sánh băm sẽ không hiệu quả vì sự khác biệt một ký tự sẽ dẫn đến hàm băm hoàn toàn khác
slhck

17
Xem thêm Facebook có lưu trữ mật khẩu văn bản đơn giản không? trên Bảo mật thông tin cho các cách khác để phát hiện sự tương tự chỉ được cung cấp hàm băm của mật khẩu cũ và bản rõ của mật khẩu mới (không có bản rõ cho bản cũ).
Bob

21
Bạn thực sự có thể kiểm tra sự giống nhau giữa mật khẩu cũ được băm và mật khẩu mới rõ ràng. Chỉ cần tạo một danh sách các mật khẩu tương tự như mật khẩu mới, băm tất cả chúng và so sánh các băm kết quả với hàm băm mật khẩu cũ. Nếu bất kỳ trận đấu, thì nó tương tự.
BWG

2
@BWG: Đó là một sự đơn giản hóa một chút - kế hoạch băm hiện tại muối băm, vì vậy trước tiên bạn phải trích xuất muối từ hàm băm mật khẩu cũ và đảm bảo bạn sử dụng muối đó cho mật khẩu tương tự mới của mình. (Tôi đang chỉ ra điều này vì có thể API sẽ không tiết lộ cách ép một loại muối cụ thể.)
Ulrich Schwarz

Câu trả lời:


156

Vì bạn cần cung cấp cả mật khẩu cũ mật khẩu mới khi sử dụng passwd, chúng có thể dễ dàng so sánh trong văn bản gốc, trong bộ nhớ mà không cần ghi chúng ở đâu đó trên ổ đĩa.

Thật vậy, mật khẩu của bạn được băm khi cuối cùng được lưu trữ, nhưng cho đến khi điều đó xảy ra, công cụ nhập mật khẩu của bạn dĩ nhiên có thể truy cập trực tiếp như bất kỳ chương trình nào khác có thể truy cập vào những thứ bạn đã nhập trên bàn phím trong khi nó đang đọc từ STDIN.

Đây là một tính năng của hệ thống PAM được sử dụng trong nền của passwdcông cụ. PAM được sử dụng bởi các bản phân phối Linux hiện đại.

Cụ thể hơn, pam_crackliblà một mô-đun cho PAM cho phép từ chối mật khẩu dựa trên một số điểm yếu sẽ khiến chúng rất dễ bị tổn thương.

Nó không chỉ là mật khẩu quá giống nhau mà có thể được coi là không an toàn. Các mã nguồn có các ví dụ khác nhau về những gì có thể được kiểm tra, ví dụ như xem một mật khẩu là một palindrome hoặc những gì các chỉnh sửa khoảng cách giữa hai từ. Ý tưởng là làm cho mật khẩu chống lại các cuộc tấn công từ điển.

Xem thêm các pam_cracklibmanpage.


bạn có ý tưởng nào trong "làm thế nào" lời giải thích của bạn phù hợp với các lập luận được báo cáo trong câu trả lời của tôi không? Có hai cách tiếp cận khác nhau, được thực hiện bởi ứng dụng "passwd", khi máy chủ không nhận biết PAM? PS: Không có chỉ trích nào cả. Tôi chỉ đang tự hỏi (như PAM, BTW, là phỏng đoán đầu tiên của tôi ... ngay trước khi lấy mã nguồn).
Damiano Verzulli

27
Đáng lo ngại hơn là các quy tắc mật khẩu của công ty cảnh báo bạn nếu bạn đã sử dụng cùng một mật khẩu hoặc tương tự trong số bốn quy tắc cuối cùng.
Nick T

4
@NickT Làm thế nào điều đó (nhất thiết) đáng lo ngại - họ không thể lưu 4 băm cuối cùng của bạn, sau đó so sánh từng băm với đề xuất mới của bạn theo cách tương tự như câu hỏi này?
neminem

1
@neminem "... hoặc tương tự"
Nick T

1
@NickT Ah, đủ công bằng, bởi vì trong trường hợp cụ thể này, bạn đang so sánh với "mật khẩu cũ" mà người dùng nhập vào để thay đổi mật khẩu, thay vì chống lại hàm băm đã lưu. Tuy nhiên, bạn có thể sử dụng giả thuyết phương pháp mà BWG đã đăng trong một bình luận, để ít nhất kiểm tra các thay đổi thực sự đơn giản (thay thế một ký tự, thêm / xóa một ký tự, v.v.).
neminem

46

Ít nhất là trong Ubuntu của tôi, các thông báo "quá giống nhau" đã xuất hiện khi: "... hơn một nửa số ký tự là khác nhau ...." (xem bên dưới để biết chi tiết). nhờ hỗ trợ PAM, như được giải thích rõ ràng trong câu trả lời @slhck.

Đối với nền tảng khác, nơi PAM không được sử dụng, các thông báo "quá giống nhau" xuất hiện khi: "... hơn một nửa số ký tự là khác nhau ...." (xem bên dưới để biết chi tiết)

Để tự mình kiểm tra tuyên bố này, bạn có thể kiểm tra mã nguồn. Đây là cách làm.

Chương trình "passwd" được bao gồm trong gói passwd:

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

Khi chúng tôi đang xử lý các công nghệ Nguồn mở, chúng tôi có quyền truy cập không hạn chế vào mã nguồn. Bắt nó đơn giản như:

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

Sau đó, thật dễ dàng để tìm thấy đoạn mã có liên quan:

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");

Một kiểm tra nhanh để "obscure.c" đưa ra điều này (Tôi chỉ cắt và dán đoạn mã có liên quan):

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;
}

Vì vậy, bây giờ, chúng ta biết rằng có một chức năng "tương tự" dựa trên kiểm tra cái cũ và cái mới nếu cả hai đều giống nhau. Đây là đoạn trích:

/*
 * 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;
}

Tôi chưa xem lại mã C. Tôi giới hạn bản thân trong việc tin tưởng nhận xét ngay trước khi định nghĩa hàm :-)


Sự khác biệt giữa các nền tảng nhận biết PAM và NON-PAM được xác định trong tệp "obscure.c" có cấu trúc như sau:

#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
Đây là một câu trả lời dài mà dường như không trả lời trực tiếp câu hỏi làm thế nào nó có thể so sánh với mật khẩu cũ khi mật khẩu được băm.
jamesdlin

10
@jamesdlin: như đã nêu trong nhận xét của Rinzwind cho câu hỏi ban đầu, băm không đóng vai trò nào trong vấn đề này: khi bạn ban hành lệnh "passwd" để thay đổi mật khẩu, bạn bắt buộc phải cung cấp cả mật khẩu "cũ" và "mới". Vì vậy, mã "passwd" hoàn toàn không có vấn đề gì trong việc so sánh / kiểm tra cả mật khẩu cùng một lúc (ở dạng rõ ràng; không bị băm chút nào).
Damiano Verzulli

3
@DamianoVerzulli Tuy nhiên, điều này không thực sự giải quyết câu hỏi. Câu hỏi không phải là "bạn sử dụng mã C nào để nói nếu hai chuỗi giống nhau;" điều đó giống hệt với mật khẩu như đối với mọi thứ khác. Điều về mật khẩu làm cho chúng thú vị là chúng không bao giờ được lưu trữ trong bản rõ và đó là những gì câu hỏi hỏi về. Câu trả lời này "tiêu chí nào được sử dụng và cách thực hiện trong C", nhưng quá dài cho "tiêu chí nào" và "làm thế nào để tôi làm điều này trong C" là một câu hỏi SO, không phải là câu hỏi SU.
cpast

7
@DamianoVerzulli Và thực tế là passwdyêu cầu cả mật khẩu cũ và mật khẩu mới là câu trả lời . Phần còn lại của câu trả lời này là không liên quan.
jamesdlin

3
+1 cho và câu trả lời cực kỳ phù hợp và thú vị! Thật tuyệt khi thấy rằng mã thực tế so sánh mật khẩu thực sự hoạt động trên bản rõ và, như mong đợi, không phải trên hàm băm.
nico

36

Câu trả lời đơn giản hơn nhiều so với bạn nghĩ. Trên thực tế, nó gần như đủ điều kiện là ma thuật, bởi vì một khi bạn giải thích mánh khóe, nó đã biến mất:

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

Password changed successfully

Nó biết mật khẩu mới của bạn tương tự ... Bởi vì bạn đã gõ mật khẩu cũ chỉ trong giây lát.


2
"... hoặc kẹo."
Nick T

1
Thỏ ngớ ngẩn, trix là dành cho trẻ em!
iAdjunc

1
Điều nó không giải thích là khi nó biết mật khẩu n trước đây của bạn :) "Mật khẩu đã được sử dụng quá gần đây", điều này ngăn việc hoán đổi cùng một vài mật khẩu trong môi trường công ty.
Juha Untinen

3
@Juha Untinen: Đó là sự thật, nhưng điều đó có thể được xử lý bằng cách chỉ cần nhớ các băm N cuối cùng. Nắm bắt "giống như mật khẩu Nth" rất dễ, " tương tự như mật khẩu Nth" rất khó. Theo như tôi biết, các hệ thống này chỉ kiểm tra sự giống nhau với mật khẩu cuối cùng và sự giống nhau với chữ N cuối cùng. Nếu chúng kiểm tra sự tương đồng với N cuối cùng ... đó là một mẹo thực sự thú vị bây giờ, không phải vậy! Tôi không biết làm thế nào họ làm điều đó.
Cort Ammon

7

Mặc dù các câu trả lời khác là đúng, nhưng có thể đáng để đề cập rằng bạn không cần cung cấp mật khẩu cũ để làm việc này!

Trong thực tế, người ta có thể tạo ra một loạt mật khẩu tương tự như mật khẩu mới mà bạn đã cung cấp, băm chúng, sau đó kiểm tra xem có bất kỳ băm nào phù hợp với mật khẩu cũ không. Nếu đây là trường hợp, thì mật khẩu mới được đánh giá tương tự như mật khẩu cũ! :)


2
Mặc dù đây thực sự là một phương tiện để đạt được kỳ tích này (và được sử dụng bởi nhiều trang web), nhưng đó không phải là những gì đang diễn ra trong trường hợp này.
Brian S

Đó là một mẹo gọn gàng! Một chút tính toán chuyên sâu hơn, nhưng thông minh!
Cort Ammon

Ít nhất bạn nên đưa ra một số ước tính về việc cần tạo bao nhiêu mật khẩu tương tự để có một kiểm tra có ý nghĩa hoặc liên kết với tài nguyên bên ngoài. Mặt khác, đây chỉ là một ý tưởng có thể thay thế, không phải là một câu trả lời rõ ràng.
hyde

@hyde mà phụ thuộc vào tiêu chí ai đó có thể nghĩ ra. Đối với tôi mật khẩu tương tự nếu có tối đa 3 ký tự được thêm / xóa / sửa đổi. Vì vậy, đó là 62 băm cho mỗi ký tự (và đó là nếu chúng ta chỉ sử dụng kết hợp 3 chữ số) với 3 lần từ độ dài mật khẩu ( n), 62 * (n!)/(6 * (n - 3)!)bằng 13540 cho mật khẩu dài 12 ký tự. Nhưng nếu bất cứ ai nghĩ về một cái gì đó khác nhau, phương trình là vô dụng, vậy tại sao phải bận tâm?
Killah

Câu trả lời ngu ngốc, nhưng một cái nhìn sâu sắc tuy nhiên. Tại sao ngu ngốc? 1. Bạn sẽ phải tạo ra số lượng băm không thể tưởng tượng được. 2. Thiết lập như vậy sẽ làm suy yếu tính bảo mật của mật khẩu gốc. Nếu ai đó có được băm của tất cả các mật khẩu tương tự thay vì chỉ một hàm băm, họ sẽ có thời gian dễ dàng hơn để bẻ khóa nó.
Rok Kralj

5

Một khía cạnh không được đề cập: lịch sử mật khẩu. Một số hệ thống hỗ trợ này. Để làm điều đó, nó giữ một lịch sử mật khẩu và mã hóa chúng bằng mật khẩu hiện tại. Khi bạn thay đổi mật khẩu, nó sẽ sử dụng mật khẩu "cũ" để giải mã danh sách và xác minh. Và khi nó đặt mật khẩu mới, nó sẽ lưu danh sách (một lần nữa) được mã hóa bằng một khóa có nguồn gốc từ mật khẩu mới.

Đây là cách làm remember=Nviệc trong PAM (được lưu trữ trong /etc/security/opasswd). Nhưng Windows và các nhà cung cấp Unix khác cũng cung cấp các chức năng tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.