【问题标题】:Php's password_hash encoding for HTTP basic authentication用于 HTTP 基本身份验证的 PHP 的 password_hash 编码
【发布时间】:2015-05-09 21:55:40
【问题描述】:

我的问题:

我需要基于 HTTP 的基本身份验证(客户端无法承受 HTTPS)。所以我不担心通信是否没有加密。我只是想防止某些用户嗅探和使用密码(网站仅用于上传照片,这些照片是公开的。)。

我可以使用的工具箱:

  1. Javascript
  2. PHP
  3. Sha512.js

PHP 和 JS 的 SHA 算法是一样的:

证明:(?)

<?php 
$password= "password";
echo hash('sha512',$password);
//outputs: b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
?>

在 JS 中(我所有的文件都用 utf8 编码)

document.getElementById("hiddenField").value
= JS.sha512("password");
//outputs b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86

但是我不能简单地在每个连接上发送相同的哈希,否则任何人都可以嗅探它并将其发送到连接。

所以我的想法是使用password_hash() 函数作为盐生成器。

salt 是公开的,(password+salt) 的哈希是公开的,但是密码是私有的并且永远不会以明文形式发送:服务器将(希望)从客户端计算与 JS 中相同的哈希并验证两个哈希匹配。

问题是,无论我做什么,当我散列该函数的输出(password_hash) 时,我都无法获得相同的输出。好像和编码有关。

我想使用password_hash(),因为它已经考虑了很多安全问题:

Javascript:

document.getElementById("hiddenField").value
= JS.sha512("password" +  document.getElementById("publicToken").value);

我将“password_hash”内容放入另一个我称之为“publicToken”的隐藏表单字段中。无论我做什么,我都无法获得哈希匹配:

<?php 
$salt = ut8_encode(password_hash("another_password")); //doesn't work either

最后,我该怎么做才能得到正确编码的盐?

<?php
$salt = //... one time usage salt.. but what to put here?

【问题讨论】:

  • 嗨达里奥,你似乎有冲突的要求:So I don't warry If communication is not crypted. I just want to prevent some user can sniff and use the password。此外,如果 JS 本身至少不是通过 HTTPS 提供的,那么您在 JS 中所做的任何加密都是毫无价值的。最后,“买不起 HTTPS”似乎非常奇怪,因为有很多非常便宜的证书提供者,甚至可能是免费的......这听起来像是一个解决解决方案的发明问题。
  • 您是否考虑过使用已经存在的 HTTP 摘要式访问身份验证?
  • 您假设攻击者不会简单地进入登录页面的中间并剥离您使用的任何客户端加密或注入 JavaScript 键盘记录器。
  • 任何允许存储数百兆的 webiste + 数据库和 HTTPS 的免费 Web 服务示例?如果你举个例子,那么问题是发明的,否则不是

标签: passwords php javascript


【解决方案1】:

如果没有公钥加密和验证服务器身份的方法(换句话说,HTTPS),不幸的事实是根本无法将通信保护到可接受的水平。我什至不建议尝试,因为害怕得到错误的安全感。不管你用多少哈希和盐,它只会比发送明文密码好一点点,而且很容易破解。

如果您的客户买不起证书,我建议您查看StartSSL。他们的基础级别证书是完全免费的;我相信它们的有效期为 1 年,并且可以无限续订。

另一个值得关注的项目是Let's Encrypt。他们试图让获取证书的过程变得更简单、更易于访问,因此他们开发了一种方法来完全自动化颁发(免费)证书的过程。不幸的是,该服务尚未上线;他们计划在今年夏天开始颁发证书。引用他们的页面:

任何经历过建立安全网站的麻烦的人 知道获得证书有多麻烦。让我们加密 自动消除所有这些痛苦并让站点运营商打开 HTTPS 只需单击一下或使用 shell 命令。

当 Let's Encrypt 在 2015 年年中推出时,为您的网站启用 HTTPS 将像安装一小块证书管理一样简单 服务器上的软件:

$ sudo apt-get install lets-encrypt

$ lets-encrypt example.com

这就是它的全部内容! https://example.com 立即上线。

Let's Encrypt 管理软件将:

  • 自动向 Let's Encrypt CA 证明您控制了网站
  • 获取浏览器信任的证书并将其设置在您的网络服务器上
  • 跟踪您的证书何时到期并自动续订
  • 在必要时帮助您撤销证书。

没有验证邮件,没有复杂的配置编辑,没有过期 证书破坏您的网站。当然,因为让我们 Encrypt免费提供证书,无需安排付款。

【讨论】:

  • 证书无关。客户端根本负担不起任何托管费用,因此它使用不提供 HTTPS 的 altervista,不管我可以生成免费证书的事实。然后我将恢复到 B 计划,即在网站上的任何操作之前向客户发送带有确认链接的电子邮件(我将使用其网络邮件服务的 HTTPS)
【解决方案2】:

我知道您的客户买不起标准的 HTTPS 证书,但老实说,即使是免费的 SSL 证书也可能比您在这里制作的要好得多。

在这种情况下,您所要做的就是将浏览器端的哈希值设为用户密码,而要进入,只需发送一个匹配的哈希值即可。如果您决定这样做,您肯定需要在服务器端再次对密码进行哈希处理,但它仍然无法替代 SSL。

更多信息在这里:https://crackstation.net/hashing-security.htm

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 2016-10-31
    • 2017-05-31
    • 1970-01-01
    • 2011-03-29
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多