Câu hỏi 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?


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

Tôi luôn tự hỏi, làm sao 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 cho sự giống nhau, mật khẩu cũ thực sự được lưu dưới dạng văn bản thuần túy?


140
2017-12-27 17:22


gốc


1st off: plain text? Không. Nếu (!) Lưu bạn lưu băm và so sánh 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
@Rinzwind Nhưng so sánh hashes sẽ không hoạt động vì một sự khác biệt một nhân vật nên kết quả trong một băm hoàn toàn khác nhau - slhck
Xem thêm Facebook có lưu trữ mật khẩu thuần văn bả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 băm của mật khẩu cũ và bản rõ của mật khẩu mới (không có chữ thô cho cũ). - Bob
Bạn thực sự có thể kiểm tra sự giống nhau giữa mật khẩu cũ băm và mật khẩu mới. 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 băm mật khẩu cũ. Nếu bất kỳ trận đấu nào, thì nó giống nhau. - BWG
@ BWG: Đó là một sự đơn giản hóa quá mức - các chương trình 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ừ băm mật khẩu cũ và chắc chắn rằng bạn sử dụng muối đó cho mật khẩu tương tự mới. (Tôi đang chỉ ra điều này vì có thể API sẽ không vạch ra một cách để buộc một loại muối cụ thể.) - Ulrich Schwarz


Các câu trả lời:


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

Thật vậy, mật khẩu của bạn được băm khi nó được lưu trữ, nhưng cho đến khi điều đó xảy ra, công cụ mà bạn đang nhập mật khẩu 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 những thứ bạn đã nhập trên bàn phím trong khi đọ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 passwd dụ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_cracklib là 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 có thể 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ụ: cho dù mật khẩu là palindrome hay khoảng cách chỉnh sửa nằm giữa hai từ. Ý tưởng là để làm cho mật khẩu có khả năng chống lại các cuộc tấn công từ điển.

Xem thêm các pam_cracklib manpage.


155
2017-12-27 19:27



bạn có ý tưởng trong "cách" giải thích của bạn phù hợp với các đối số đượ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ủ lưu trữ là không phải PAM-nhận thức? Tái bút: Không có nhà phê bình nào cả. Tôi chỉ tự hỏi (như PAM, BTW, là dự đoán đầu tiên của tôi ... ngay trước khi grepping mã nguồn). - Damiano Verzulli
Điều đá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 cho bạn nếu bạn đã sử dụng cùng một mật khẩu tương tự hoặc bất kỳ trong bốn lần cuối cùng. - Nick T
@ NickT Làm thế nào là (nhất thiết) đáng lo ngại - không phải họ chỉ cần lưu 4 băm cuối cùng của bạn, sau đó so sánh từng cái với cái mới được đề xuất của bạn giống như câu hỏi này? - neminem
@neminem "... hoặc tương tự" - Nick T
@NickT Ah, đủ công bằng, bởi vì trong trường hợp cụ thể này, bạn so sánh với "mật khẩu cũ" do người dùng nhập vào để thay đổi mật khẩu, thay vì chống lại băm đã lưu. Vẫn là bạn có thể giả sử sử dụng phương pháp BWG được đăng trong một bình luận, ít nhất là kiểm tra các thay đổi thực sự đơn giản (thay thế một ký tự, một ký tự được thêm vào / gỡ bỏ, vv). - neminem


Ít nhất trong Ubuntu của tôi, các thông báo "quá giống" khi nào: "... hơn một nửa số nhân vật 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, thông báo "quá tương tự" xuất hiện khi: "... hơn một nửa số nhân vật khác nhau ..." (xem chi tiết bên dưới)

Để tự mình kiểm tra lại 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 ta đang xử lý các công nghệ Nguồn mở, chúng tôi có quyền truy cập không giới hạn vào mã nguồn. Bắt nó đơn giản như:

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

Sau đó rất dễ dàng để tìm đ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");

Kiểm tra nhanh đến "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 cái cũ và kiểm tra 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 xét mã C. Tôi giới hạn bản thân mình trong việc tin tưởng nhận xét ngay trước định nghĩa hàm :-)


Sự khác biệt giữa các nền tảng nhận thức PAM và NON-PAM được định nghĩa 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 */

45
2017-12-28 18:14



Đâ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 về cách nó có thể so sánh với mật khẩu cũ khi mật khẩu được băm. - jamesdlin
@jamesdlin: như đã nêu trong Rinzwind bình luận cho câu hỏi ban đầu, băm làm KHÔNG PHẢI đóng bất kỳ vai trò nào trong vấn đề này: khi bạn đưa ra lệnh "passwd" để thay đổi mật khẩu, bạn được yêu cầu cung cấp cả mật khẩu "cũ" và "mới". Vì vậy, "passwd" mã không có vấn đề gì cả trong việc so sánh / kiểm tra cả hai mật khẩu cùng một lúc (trong các hình thức rõ ràng; không băm ở tất cả). - Damiano Verzulli
@DamianoVerzulli Tuy nhiên, điều này không thực sự giải quyết các câu hỏi. Câu hỏi không phải là "bạn sử dụng mã C nào để biết hai chuỗi có giống nhau không;" đó là chính xác như nhau cho mật khẩu như cho bất cứ điều gì khác. Điều về mật khẩu điều đó khiến họ thú vị là họ không bao giờ được lưu trữ trong bản rõ, và đó là những gì câu hỏi đặt ra. Điều này trả lời "tiêu chí nào được sử dụng và cách nó được thực hiện trong C", nhưng quá dài cho "tiêu chí" và "cách tôi thực hiện điều này trong C" là câu hỏi SO chứ không phải câu hỏi SU. - cpast
@DamianoVerzulli Và thực tế là passwd yêu cầu cả mật khẩu cũ và 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 thích hợp. - jamesdlin
+1 cho và câu trả lời cực kỳ có liên quan và thú vị! Thật tuyệt khi thấy rằng mã so sánh mã thực tế thực sự hoạt động trên bản rõ và, như mong đợi, không phải trên băm. - nico


Câu trả lời đơn giản hơn bạn nghĩ. Trong thực tế, nó gần như đủ điều kiện như ma thuật, bởi vì một khi bạn giải thích các trick, 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 là tương tự ... Bởi vì bạn đã gõ mật khẩu cũ chỉ trong giây lát trước đây.


37
2017-12-29 13:41



"... hoặc kẹo." - Nick T
Thỏ ngớ ngẩn, trix dành cho trẻ em! - iAdjunct
Những gì nó không giải thích là khi nó biết mật khẩu n trong quá khứ của bạn :) "Mật khẩu đã được sử dụng quá gần đây", ngăn ngừa trao đổi cùng một vài mật khẩu trong một môi trường công ty. - Juha Untinen
@Juha Untinen: Đó là sự thật, nhưng điều đó có thể được xử lý bằng cách đơn giản nhớ N băm cuối cùng. Bắt "giống như mật khẩu Nth" rất dễ dàng, đó là "giống 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 N. cuối cùng Nếu chúng kiểm tra sự giống nhau với N cuối cùng ... đó là một điều thú vị Tôi không biết họ sẽ làm thế nào. - Cort Ammon


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

Trong thực tế, người ta có thể tạo ra một loạt các mật khẩu tương tự như mật khẩu mới mà bạn cung cấp, băm chúng, và sau đó kiểm tra nếu bất kỳ của các hash phù hợp với cũ. 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ũ! :)


8
2018-01-02 11:06



Trong khi điều này thực sự là một phương tiện để đạt được điều này feat (và được sử dụng bởi nhiều trang web), đó không phải là những gì đang xảy ra trong trường hợp này. - Brian S
Đó là một mẹo nhỏ gọn! Một chút tốn kém hơn tính toán, nhưng thông minh! - Cort Ammon
Ít nhất bạn nên đưa ra một số ước tính về số lượng mật khẩu tương tự sẽ cần được tạo ra để có một kiểm tra có ý nghĩa hoặc liên kết đến tài nguyên bên ngoài. Nếu không thì đây chỉ là ý tưởng về sự thay thế có thể, chứ không phải là một câu trả lời được chứng minh. - hyde
@ hyde phụ thuộc vào tiêu chí ai đó có thể nghĩ đến. Đố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 nhân vật (và đó là nếu chúng ta chỉ sử dụng chữ số) lần kết hợp của 3 từ chiều dài của mật khẩu (n), đó là 62 * (n!)/(6 * (n - 3)!), bằng 13540 cho mật khẩu dài 12 ký tự. Nhưng nếu có ai đó nghĩ về điều gì đó khác thì phương trình là vô dụng, vậy tại sao lạ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. Tại sao ngu ngốc? 1. Bạn sẽ phải tạo ra một 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 bảo mật của mật khẩu ban đầu. 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 băm, họ sẽ có nhiều thời gian dễ dàng hơn để crack nó. - Rok Kralj


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ợ điều này. Để làm điều đó, nó giữ một lịch sử của mật khẩu và mã hóa chúng với mật khẩu hiện tại. Khi bạn thay đổi mật khẩu của mình, mật khẩu sẽ sử dụng mật khẩu "cũ" để giải mã danh sách và xác minh. Và khi nó thiết lập một mật khẩu mới, nó sẽ lưu danh sách (một lần nữa) được mã hóa với một khóa bắt nguồn từ mật khẩu mới.

Đây là cách remember=N hoạt động 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ự.


4