![在典型的 Unix(例如 Gnu/Linux)中,使用什么加密机制将密码存储在“/etc/shadow”中?](https://linux22.com/image/167518/%E5%9C%A8%E5%85%B8%E5%9E%8B%E7%9A%84%20Unix%EF%BC%88%E4%BE%8B%E5%A6%82%20Gnu%2FLinux%EF%BC%89%E4%B8%AD%EF%BC%8C%E4%BD%BF%E7%94%A8%E4%BB%80%E4%B9%88%E5%8A%A0%E5%AF%86%E6%9C%BA%E5%88%B6%E5%B0%86%E5%AF%86%E7%A0%81%E5%AD%98%E5%82%A8%E5%9C%A8%E2%80%9C%2Fetc%2Fshadow%E2%80%9D%E4%B8%AD%EF%BC%9F.png)
(从新手的角度来说)
有一天,我在思考典型的“passwd”命令如何在 LINUX 操作系统中工作。例如,当我们输入“passwd”时,会出现一个提示让我们输入密码,然后它会用加密算法保存该密码,然后保存在/etc/影子。所以我带来了我自己的“密码/登录模拟”。最初,它将用户名及其密码保存在名为的文件中芒果.txt以“用户名::密码”的形式,下次同一用户尝试登录时,它会要求输入用户名和密码。所以我想出了这两个脚本。
脚本 1:提示输入用户名和密码并将其保存在名为 mango.txt 的文件中。
# Title: username.sh
#!/bin/bash
# What I'm planning to do here is that,
#create a username script which allows a
#user to add themselves by puting in
#their
#names
# and their password at the time of
#login, it will save itself to a file
#with
#the username and password.
# If username already exists, tells the
#user that a user with the same name
#exits, else add the new user.
# along with a password. The password is
# saved in a md5 hash form.
exec 2>/dev/null
touch mango.txt
echo -n "Enter username: "
read usame
if [ "$usame" == "" ]; then echo -e "Username can not be blank\n"
./username.sh
else
grep -q $usame mango.txt
if [ "$?" == 0 ]; then
echo -e "A username with the same name already exists\n"
./username.sh
else
echo -n "Password: "
read -s -p "Password: " passwd
while true; do
if [ "$passwd" == "" ]; then echo -e "Password can not be blank\n"
else
echo $usame::$(echo $passwd | md5sum) >> mango.txt
echo -e "\nUser $usame added\n"
break
fi
done
fi
fi
脚本 2:如果可以将其添加到“bash.bashrc”中,那么它将在每次终端启动时运行,并询问用户名和密码。如果用户名和密码与 mango.txt 中的一致,则允许用户登录,否则终端退出(;纯密码以 md5sum 形式与 mango.txt 文件密码进行比较。
#Title: login.sh
# A simple login bash script
#trap interrupts your keyboard if you
#press ctrl+z or ctrl+c
trap '' INT TSTP
read -p "Enter username: " usname
grep -q $usname mango.txt
if [ "$?" -gt 0 ]; then
echo "Username not found"
sleep 1
pkill -9 bash #That's a bit too much I guess, but oh well
else
read -s -p "Password: " password
if [ "$password" == "" ]; then
echo "Password can not be blank"
./login.sh
else
#saves the password in md5sum format in tmp.txt
echo $password | md5sum > tmp.txt
tmp="$(cat tmp.txt)"
#if the md5 hashes match, then allow login saying yo
cat mango.txt | grep -q $usname::$tmp
if [ "$?" == 0 ]; then
echo -e "\nyo"
#else print login failed
else echo -e "\nLogin failed"
sleep 1
pkill -9 bash
fi
fi
fi
rm tmp.txt
# Deletes the tmp file afterwards
我很确定这与 LINUX 系统中的工作原理相去甚远(更不用说像 ccrypt 和 scrypt 这样的密码学以及不同的加盐机制),但它是我能想到的最好的了..也许对如果专家能提供正确的指导,说明其实际运作方式,那就太好了。 (:
加密机制是我非常好奇的。
答案1
你会使用一个慢的,盐腌的,安全的哈希函数:密钥导出函数。
我们使用哈希函数来隐藏密码,没有人可以读取它,甚至管理员也无法读取。哈希值无法逆转。当用户登录时,我们对密码输入进行哈希处理,并与存储的哈希值进行比较。
加盐是在散列之前向密码添加一个大的随机字符串。我们必须将盐与哈希一起存储。我们这样做是为了减缓字典攻击。字典攻击是对已知常用密码的字典进行哈希处理,并查找匹配项。现在攻击者需要为每个用户创建一个字典(因为他们都有唯一的盐)。
我们使用慢速哈希来进一步减慢字典攻击。以每次用户登录时的计算时间为代价。
您可以阅读更多内容
- https://en.wikipedia.org/wiki/Hash_function
- https://en.wikipedia.org/wiki/Secure_Hash_Algorithms
- https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification
- https://en.wikipedia.org/wiki/Key_derivation_function
- https://www.youtube.com/watch?v=b4b8ktEV4Bg
- https://www.youtube.com/watch?v=DMtFhACPnTY
有关某些 Gnu/Linux 系统上使用的内容,请参阅此相关问题
编辑/etc/shadow
——不要这样做。