平台独立地为 Ruby 中的 /etc/shadow 以模块化加密格式 (MFC) SHA512 生成 Linux 密码

Platform-independently generate Linux password in Modular Crypt Format (MFC) SHA512 for /etc/shadow in Ruby

为了自动创建虚拟机,我从一些 Ruby 代码中生成 /etc/shadow 的密码。这是在主机上完成的。主机可以是 Linux 或 Windows.

在 linux 主机上

"mypassword".crypt("$" + "123SaLt9")

returns

3SaLt9$idgUFrrwVkpDMcoHj7SAYH0UwCY6LymbsR9yTDrelYgcZ2wstoynmLIY83qBF0/BIT4Od.rQL2g3n2jEG/VXp/

这是正确的,适用于 /etc/shadow。

但是,在一些 Windows 10台主机上(大约两周前在两个同事的机器上)同一行代码returns

MrNddDu3Hf6

这显然行不通。 (在此处观察到 MacOS 的类似行为 https://judepereira.com/blog/use-ruby-to-generate-your-shadow-password/

我忽略了这个函数依赖于平台 (https://apidock.com/ruby/String/crypt)。除了几周前它确实起作用之外,我认为我不能想当然地认为它在 Windows 10 台主机上可靠地工作。

我需要的是 returns 在 Linux 和 Windows 10 台主机上以 MFC 格式正确散列密码的解决方案。据我了解,MFC 的密码部分不仅仅是生成 SHA512 的 base64 编码结果,而是一个复杂得多的过程 (https://akkadia.org/drepper/SHA-crypt.txt, Using ruby to generate SHA512 crypt-style hashes formatted for /etc/shadow?)。我想避免在 Ruby 中自己实现算法。我做了几个小时的研究,但到目前为止找不到任何有用的东西。

关于如何在 Windows 上避免此问题的任何想法,即如何独立于平台生成这些密码哈希值?

如您所见,crypt 方法是平台相关的。它可用的算法取决于主机。 macOS 仅支持 DES。现代 Linux 发行版可能会支持所有现代密码。 Windows -- 好吧,这完全是胡说八道,取决于您 运行 Ruby 的表现。 (你是直接在Windows上使用WSL吗?运行Ruby?还有别的吗?)

最好将 crypt 排除在外,并使用库为您处理。首先,安装 unix-crypt:

gem install unix-crypt

然后用它来生成你的散列:

require 'unix_crypt'

# This is the hash you generated on Linux with crypt for your example
expected_hash = '3SaLt9$idgUFrrwVkpDMcoHj7SAYH0UwCY6LymbsR9yTDrelYgcZ2wstoynmLIY83qBF0/BIT4Od.rQL2g3n2jEG/VXp/'

# Generate the same hash using unix-crypt instead
hash = UnixCrypt::SHA512.build('mypassword', '123SaLt9')

# Verify they match (returns true)
expected_hash == hash

这对我适用于 macOS,而您的原始示例不适用于:

"mypassword".crypt("$" + "123SaLt9")
=> "MrNddDu3Hf6"

所以它应该可能 也适用于 Windows。如果没有,那么我建议你看看你的 Windows 用户是如何 运行 Ruby 并将他们切换到 Windows Subsystem for Linux 并让他们使用特定的 Linux 您正在使用的发行版。

一旦他们 Linux 启动并且 运行 他们就可以安装 Ruby 并且从 Ruby 解释器的角度来看它将 运行 在 Linux,而不是 Windows,因此它对 crypt 算法的访问应该与您拥有的相同,并且您应该能够像在原始示例中那样使用 crypt .

或者,您可以使用我的示例中的 unix-crypt 库作为生成散列的更普遍兼容的方法,无论发行版如何。