Linux
如何使用 Linux 檢查密碼?
我想從 linux 命令行檢查給定的明文密碼是否與 /etc/shadow 上的加密密碼相同
(我需要這個來驗證網路使用者。我正在執行嵌入式 linux。)
我可以訪問 /etc/shadow 文件本身。
您可以使用 awk 輕鬆提取加密密碼。然後你需要提取前綴
$algorithm$salt$
(假設這個系統沒有使用傳統的 DES,因為它現在可以被暴力破解,所以強烈反對)。correct=$(</etc/shadow awk -v user=bob -F : 'user == $1 {print $2}') prefix=${correct%"${correct#\$*\$*\$}"}
對於密碼檢查,底層 C 函式是
crypt
,但沒有標準的 shell 命令可以訪問它。在命令行上,您可以使用 Perl 單行程式碼來呼叫
crypt
密碼。supplied=$(echo "$password" | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "$prefix") if [ "$supplied" = "$correct" ]; then …
由於這不能在純 shell 工具中完成,如果你有 Perl 可用,你不妨在 Perl 中完成。(或者 Python、Ruby ……任何你可以呼叫的
crypt
函式。)警告,未經測試的程式碼。#!/usr/bin/env perl use warnings; use strict; my @pwent = getpwnam($ARGV[0]); if (!@pwent) {die "Invalid username: $ARGV[0]\n";} my $supplied = <STDIN>; chomp($supplied); if (crypt($supplied, $pwent[1]) eq $pwent[1]) { exit(0); } else { print STDERR "Invalid password for $ARGV[0]\n"; exit(1); }
在沒有 Perl 的嵌入式系統上,我會使用一個小型的專用 C 程序。警告,直接在瀏覽器中輸入,我什至沒有嘗試編譯。這是為了說明必要的步驟,而不是作為一個健壯的實現!
/* Usage: echo password | check_password username */ #include <stdio.h> #include <stdlib.h> #include <pwd.h> #include <shadow.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *argv[]) { char password[100]; struct spwd shadow_entry; char *p, *correct, *supplied, *salt; if (argc < 2) return 2; /* Read the password from stdin */ p = fgets(password, sizeof(password), stdin); if (p == NULL) return 2; *p = 0; /* Read the correct hash from the shadow entry */ shadow_entry = getspnam(username); if (shadow_entry == NULL) return 1; correct = shadow_entry->sp_pwdp; /* Extract the salt. Remember to free the memory. */ salt = strdup(correct); if (salt == NULL) return 2; p = strchr(salt + 1, '$'); if (p == NULL) return 2; p = strchr(p + 1, '$'); if (p == NULL) return 2; p[1] = 0; /*Encrypt the supplied password with the salt and compare the results*/ supplied = crypt(password, salt); if (supplied == NULL) return 2; return !!strcmp(supplied, correct); }
另一種方法是使用現有程序,例如
su
或login
。事實上,如果可以的話,最好安排 Web 應用程序通過su -c somecommand username
. 這裡的困難是將密碼提供給su
; 這需要一個終端。模擬終端的常用工具是expect,但它對嵌入式系統來說是一個很大的依賴項。此外,雖然su
在 BusyBox 中,但它經常被省略,因為它的許多用途要求 BusyBox 二進製文件是 setuid root。儘管如此,如果你能做到,從安全的角度來看,這是最可靠的方法。