Php 根据包含APR1-MD5密码哈希的文件检查键入的密码

Php 根据包含APR1-MD5密码哈希的文件检查键入的密码,php,apache,md5,Php,Apache,Md5,我正在一个网站上工作,该网站正在尝试从Apache身份验证切换到登录时用户名/密码的PHP身份验证。密码当前存储在一个文件中,并以Apache自己的md5格式进行加密(例如,$apr1$z6hoasr5$0Kk7p/8Hfhy9nBxu/hFUj1) 密码不存储在数据库中 现在,我正在编写一个PHP登录脚本。我的问题是,如何检查键入的密码是否与文件中的加密密码相同?我找到了基于纯文本密码生成APR1-MD5的代码,但这不是我需要的,因为它生成的代码与文件中的不同 长话短说,有没有一种方法可以相同

我正在一个网站上工作,该网站正在尝试从Apache身份验证切换到登录时用户名/密码的PHP身份验证。密码当前存储在一个文件中,并以Apache自己的md5格式进行加密(例如,
$apr1$z6hoasr5$0Kk7p/8Hfhy9nBxu/hFUj1

密码不存储在数据库中

现在,我正在编写一个PHP登录脚本。我的问题是,如何检查键入的密码是否与文件中的加密密码相同?我找到了基于纯文本密码生成APR1-MD5的代码,但这不是我需要的,因为它生成的代码与文件中的不同

长话短说,有没有一种方法可以相同地检查键入的密码是否确实是保存在文件中的密码

我知道Apache有生成这些代码的开源代码,但代码是用C编写的,我对C几乎一无所知


当然有一种方法可以在不更改每个用户密码的情况下从Apache身份验证迁移到PHP?

据我所知,密码来自您的登录函数。您必须根据APR1-md5哈希值检查此密码。如果您的登录页面不包含任何用户名,则很难进行搜索。但如果您有相应密码的用户名,则可以实现:

假设登录函数发送两个参数:$username和$password。将APRI-md5密码文件称为“password.txt”。我将解释的方法仅适用于password.txt文件中有用户名且登录脚本中的用户名与password.txt文件中的用户名相同的情况

$apr1$z6hoasr5$0Kk7p/8Hfhy9nBxu/hFUj1
密码哈希包含三个部分:

apr1
=格式标识符[静态,每个密码行相同]

z6hoasr5
=salt文本[每个密码不同]

0Kk7p/8Hfhy9nBxu/hFUj1
=实际md5哈希字符串

除非使用相同的salt文本,否则即使输入文本相同,也无法通过此方法生成相同的密码。因此,要生成相同的哈希字符串并与输入进行比较,您必须知道给定用户的salt文本是什么


例如,当您从登录脚本获得$username和$password时,您应该在password.txt文件中找到username。然后您应该从password.txt中提取salt文本部分(在您的示例中为“z6hoasr5”)。然后使用这个salt文本和$password[来自login],您应该生成APR1-md5哈希。(您可以修改以将$salt作为输入参数。因此,您可以发送salt和文本并获取密码哈希)。如果密码正确,则使用password.txt中的salt文本新创建的哈希字符串将与password.txt相同。然后您可以进行字符串比较以检查密码是否有效。

我自己也遇到了这个问题,我想我应该发布一个好的解决方案。我从人们以前的工作开始,把它打磨成一个完整的框架

composer.json:

"require": {
  "whitehat101/apr1-md5": "~1.0"
}
使用:


由于没有对.htpasswd文件进行I/O操作,我认为该库几乎涵盖了使用Apache的APR1-MD5哈希所需的所有操作。

这里有一些示例代码:。可能与我在问题中提到的代码重复-它生成新的APR1-MD5哈希,但是它们和passwd文件中的不一样,所以对我来说没用。如果我这样做,我可能会为每个用户分配一个新的随机密码。我不知道答案,但我建议您有一个带有密码字段的用户数据库。当用户输入密码时,PHP脚本首先检查数据库。如果密码不在其中,它会检查Apache文件,如果密码正确,它会将其写入数据库(使用MySQL加密或其他方式)。这样,您将得到一个更持久可行的解决方案。它不是重复的,我已经阅读了这个问题,而且,我不是要生成新的散列,我需要能够检查键入的密码是否与已保存的散列相对应。由于该代码生成不同的散列,因此对我来说根本没有用处。
// Check plaintext password against an APR1-MD5 hash
APR1_MD5::check('plaintext', '$apr1$z6hoasr5$0Kk7p/8Hfhy9nBxu/hFUj1'); // bool

// Hash a password with a known salt
echo APR1_MD5::hash('PASSWORD', 'z6hoasr5');

// Hash a password with a secure random salt
echo APR1_MD5::hash('PASSWORD');