我需要手动编辑/etc/shadow
以更改虚拟机映像内的 root 密码。
是否有命令行工具可以接受密码并/etc/shadow
在标准输出上生成兼容的密码哈希?
答案1
您可以使用以下命令来实现相同的目的:
方法1(md5、sha256、sha512)
openssl passwd -6 -salt xyz yourpass
注意:传递-1
会生成MD5密码、-5
SHA256和-6
SHA512(推荐)
方法2(md5、sha256、sha512)
mkpasswd --method=SHA-512 --stdin
该选项--method
接受md5
,sha-256
和sha-512
方法3(des、md5、sha256、sha512)
正如 @tink 所建议的,我们可以使用以下命令更新密码chpasswd
:
echo "username:password" | chpasswd
或者您可以使用带有 的加密密码chpasswd
。首先使用以下命令生成它:
perl -e 'print crypt("YourPasswd", "salt", "sha512"),"\n"'
然后您可以使用生成的密码进行更新/etc/shadow
:
echo "username:encryptedPassWd" | chpasswd -e
加密后的密码我们也可以用这个密码创建一个新用户,例如:
useradd -p 'encryptedPassWd' username
答案2
在 Ubuntu 12.04 上,有 mkpasswd (来自 whois 包):Overfeatured front end to crypt(3)
mkpasswd -m sha-512 -S saltsalt -s <<< YourPass
在哪里:
-m
= 使用 TYPE 方法计算密码。如果 TYPE 有帮助,则打印可用的方法。-S
= 使用的盐。
例如
$ mkpasswd -m help
-s = Read password from stdin
答案3
该解决方案具有以下优点:
无需额外安装
不将密码存储在您的 shell 历史记录中
为您生成随机盐
使用现代、强大的哈希算法 SHA-512
重新提示输入密码以避免错误。
$ python3 -c "from getpass import getpass; from crypt import *; \ p=getpass(); print('\n'+crypt(p, METHOD_SHA512)) \ if p==getpass('Please repeat: ') else print('\nFailed repeating.')"
Python 3.12 之后
编辑:随着 Python 3.13 中该模块的弃用crypt
,可以使用以下代码片段:
import os, base64, ctypes, getpass
salt = base64.b64encode(os.urandom(16), altchars=b"./").rstrip(b"=")
crypt = ctypes.CDLL("libcrypt.so.2").crypt
crypt.restype = ctypes.c_char_p
p=getpass.getpass()
if p==getpass.getpass("Please repeat: "):
print("\n"+crypt(p.encode(), b"$6$"+salt).decode())
else:
print("\nFailed repeating.")
它生成一个随机盐编码以尊重[./0-9A-Za-Z]
字母表(B64,不要与base64混淆),加载系统crypt
库(Python_crypt
模块正在使用)并调用其指定格式(SHA512)的crypt
函数以及计算条目。$6$
salt
OpenSSL 解决方案
然而,OpenSSL 经常出现在系统上并提供passwd
命令,似乎包含更新的算法自 v1.1.1 起,所以这可能更容易使用。
例如(-6
这里表示算法6,即SHA512;salt是自动生成的):
$ openssl passwd -6
Password:
Verifying - Password:
$6$BIAw/F3wLlH4qofD$2dqhHKfCZNuLScGHKFdkEBmCwtTpInOZSwglqCAAeWgDVM7duqCZLJU69/Ie2LZHJMqUeT7mbx/.HLNrH50mk1
但要小心该-salt
参数,因为它不允许空盐并允许盐中存在无效值(例如:
)。
参考
答案4
对于那些没有基于 Debian 的系统的人。 Python3 也能正常工作。
python3 -c 'import crypt, getpass; print(crypt.crypt(getpass.getpass()))'
getpass.getpass()
将在命令行上提示您输入密码。