首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Linux Shell 實現終端密碼與系統加密密碼驗證方案

     編輯:程式設計綜合問答

問題背景

開發模擬 su 命令的 Shell 腳本時,核心難點在於:

  1. 如何將用戶輸入的明文密碼與 /etc/shadow 中存儲的加密密文進行比對
  2. 驗證通過後,如何實現用戶身份切換(登錄上下文變更)

核心原理:系統加密驗證機制

Linux 系統使用 crypt(3) 函數族進行密碼加密驗證。/etc/shadow 中的密碼條目格式為:

$id$salt$encrypted
  • $id$:標識加密算法($1$=MD5, $5$=SHA-256, $6$=SHA-512, $y$=yescrypt 等)
  • $salt$:隨機鹽值
  • $encrypted$:經過鹽值混合加密後的密文

Shell 中的實現方案

方案一:調用系統 openssl passwd(推薦)

#!/bin/bash
read -s -p "Password: " input_pass
echo
# 從 /etc/shadow 提取目標用戶的加密條目
stored_hash=$(sudo getent shadow "$USER" | cut -d: -f2)
# 使用 openssl 驗證(自動解析算法、鹽值)
if openssl passwd -stdin -verify "$stored_hash" <<< "$input_pass" >/dev/null; then
    echo "驗證通過"
    # 執行 su 或 sudo 切換用戶上下文
else
    echo "密碼錯誤"
fi

方案二:使用 Perl/Python 單行腳本(兼容性更強)

# Perl 版本
perl -e 'use Authen::PAM; ...'  # 需安裝模塊

# Python 版本(標準庫即可)
python3 -c "
import crypt, pwd, sys
user = pwd.getpwnam('$USER')
if crypt.crypt(sys.argv[1], user.pw_passwd) == user.pw_passwd:
    sys.exit(0)
else:
    sys.exit(1)
" "$input_pass"

驗證後的身份切換

單純驗證密碼不會自動改變進程的用戶身份。要實現真正的登錄切換,必須調用系統調用:

  • setuid(uid) / setgid(gid):設置進程有效 UID/GID
  • execve():啟動新的 Shell 進程(如 /bin/bash)

在 Shell 腳本中,通常直接調用 su - $USER 或 sudo -u $USER 由成熟工具完成上下文切換,而非自行實現。

安全提示

  • 絕不可在腳本中明文存儲或輸出密碼
  • 讀取密碼時使用 read -s 關閉回顯
  • 臨時變量用完即 unset
  • 生產環境建議直接使用 su/sudo/pam 成熟機制

參考資源

更多實現細節可參考:CSDN 相關討論

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved