V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
muziyue
V2EX  ›  PHP

请教一下关于 password_hash 的密码安全问题

  •  
  •   muziyue · 2016-05-29 12:56:10 +08:00 · 8764 次点击
    这是一个创建于 3100 天前的主题,其中的信息可能已经有所发展或是发生改变。
    由于 password_hash 只能用 php 验证,那客户端提交是不是用要配合 https 才行
    如果没 https 的情况下, js 本地加密一下再 post 给 php 验证这样安全么?没用过这种加密,是不是应该这样用
    43 条回复    2017-03-07 12:06:07 +08:00
    owt5008137
        1
    owt5008137  
       2016-05-29 13:12:59 +08:00 via Android
    现在两层的 md5 和 sha1 都比较容易被撞库
    jasontse
        2
    jasontse  
       2016-05-29 13:22:06 +08:00 via iPad
    「 js 本地加密一下再 post 给 php 」这样除了增加前端的复杂度修改了最终提交的密码有什么不一样吗
    lslqtz
        3
    lslqtz  
       2016-05-29 13:32:58 +08:00
    不安全, http 情况下可以修改源文。
    muziyue
        4
    muziyue  
    OP
       2016-05-29 13:35:11 +08:00
    @jasontse 不然呢? post 明文?

    @lslqtz 就是说能上 https 还是上呗
    jasontse
        5
    jasontse  
       2016-05-29 13:36:33 +08:00 via iPad
    @muziyue 那我直接抓取你的密文当作密码用行不行呢
    lc4t
        6
    lc4t  
       2016-05-29 13:40:13 +08:00 via iPhone   ❤️ 1
    没有 https 那么传输过程都不可信,谁都能看。 md5/sha1 也不安全了,建议前端 bcrypt 然后 https 。
    dangyuluo
        7
    dangyuluo  
       2016-05-29 13:40:38 +08:00 via iPhone
    @jasontse 我觉得可以 https+js 加密密码的时候考虑进去时间戳
    lslqtz
        8
    lslqtz  
       2016-05-29 13:42:15 +08:00 via iPhone
    @muziyue 嗯 这样没有啥作用,需要劫持的可以直接把你的 js 改成先明文发送其他机子,再用你自己的 js 加密发送到你服务器。
    lslqtz
        9
    lslqtz  
       2016-05-29 13:44:00 +08:00 via iPhone   ❤️ 1
    吃力不讨好,该改还是改,还占资源。。要安全还是上 https 。
    iyaozhen
        10
    iyaozhen  
       2016-05-29 14:00:35 +08:00 via Android   ❤️ 2
    如果 js 只是单纯的加密密码是没用的,黑客也不用知道你原始密码,知道你加密后的密码就行,传给服务端服务端自己会解密成原始密码。 js 加密要和服务端结合才行,做到一次一密。先从服务端拿个动态 token(初始向量)然后再加密传输到服务端,这样那种一般的抓包就不行了,必须要拿到你的 js 来解密。

    当然一切前端的东西都是不可信的,不过也能提高黑客的成本,能上 https 还是上 https 吧。

    还有楼上有些同学可能对 PHP 不了解, PHP 的 password_hash 函数就是专门搞这个事情的,把密码 hash ,还可以自己加 salt ,还能保证不同密码长度完成加密时间一样。非常可靠和安全。如果后端是 PHP 的话就不要自己造轮子了。
    qqmishi
        11
    qqmishi  
       2016-05-29 14:49:17 +08:00   ❤️ 1
    建议上 https 。
    只前端加密的话,唯一的用处是中间人不能直接看到明文密码,但拦不住重放攻击,直接再发一遍这个包就破了。
    或者你加个动态验证,比如时间或者服务器发的 token 。
    SoloCompany
        12
    SoloCompany  
       2016-05-29 17:35:22 +08:00
    这问题都讨论烂了
    前端加密有任何意义吗?
    即便你都要用上非对称加密了, rsa 吧
    走 http 的话中间人直接换掉你的公钥,那就和明文没区别了
    即便不换掉你的 key
    都中间人了
    直接捕获你的密码输入,旁路提交到另一个地方又怎么了
    muziyue
        13
    muziyue  
    OP
       2016-05-29 17:42:24 +08:00
    @SoloCompany 抱歉我可没看到其他关于 password_hash 的讨论帖子
    Citrus
        14
    Citrus  
       2016-05-29 17:45:18 +08:00 via iPhone
    @muziyue 这个问题跟 password_hash 无关,而是如何安全的传输密码ˊ_>ˋ
    qgy18
        15
    qgy18  
       2016-05-29 17:46:24 +08:00   ❤️ 1
    @SoloCompany

    其实还是有一点用的,如果中间人只嗅探不改包,那么他只能拿到密文,只能用于这一个网站登录。对于不同网站使用同密码的用户来说,能提高一点安全性。

    能上 HTTPS 还是直接上 HTTPS 吧。

    抛开安全性不谈,浏览器也在逐步淘汰 HTTP : https://imququ.com/post/moving-to-https-asap.html
    shiny
        16
    shiny  
       2016-05-29 17:55:17 +08:00
    password_hash 只不过是加盐与 hash 的打包解决方案。
    muziyue
        17
    muziyue  
    OP
       2016-05-29 17:56:30 +08:00
    @Citrus 不,我本意是问一下是不是不用 https 用了 password_hash 也没啥意义
    shiny
        18
    shiny  
       2016-05-29 17:59:35 +08:00   ❤️ 1
    @muziyue 怎么会没有意义,假设你网站被脱裤,这个时候 password_hash 的作用就提现出来了嘛,不管你用的是不是 https 。
    shiny
        19
    shiny  
       2016-05-29 18:01:14 +08:00
    password_hash 的意义在于很多程序员无法正确实现 hash 和加盐。比如拿用户名去加盐就是错误实现方式的一种。
    hard2reg
        20
    hard2reg  
       2016-05-29 18:08:44 +08:00
    @owt5008137 加盐可以防止被撞。。。。

    还有,楼上的你们怎么不说别人直接在你电脑种个木马,键盘记录你密码?
    hard2reg
        21
    hard2reg  
       2016-05-29 18:09:51 +08:00
    @shiny 当有一个可用账号的时候,可以根据社会工程学,把盐给猜出来。。
    xqin
        22
    xqin  
       2016-05-29 18:10:53 +08:00   ❤️ 1
    @SoloCompany 这么看不起 HTTP? 建议你去研究一下 QQ 网页登陆( http://id.qq.com/login/ptlogin.html).
    另外前端的加密是用于解决 HTTP 请求中的数据在被别人获取之后的安全性问题的,
    你所假设的 替换公钥, 篡改 HTTP 响应包的数据, 这种问题不是 前端 加密所要解决的事情, 这是 HTTPS 的事.
    不能把这两者混为一谈.


    @iyaozhen @qqmishi 说拦不住重放的,我也建议你去研究一下 QQ 的网页登陆.


    QQ 网页上的登陆,在登陆时的流程如下:
    在用户输入完账号之后, 会有一个 ajax 请求, 服务器会根据当前账号的登陆环境等数据, 决定是否要用户输入验证码,
    在不需要输入验证码的情况下,服务器会自动返回一个验证码以及 salt.


    在登陆时,提交的密码为:(注: QQTea 第一个参数为 key, 第二个参数为 要加密的内容)
    RSA(QQTea(md5(QQ 密码 + 验证码) , md5(QQ 密码) + salt + 验证码长度 + 验证码))

    验证码是一次性的, 如果对请求进行重放, 这个验证码肯定是不对的, 且你没有腾讯的 私钥,你也解不开这个加密后的内容.

    QQTEA 的加密 key 是由用户的密码 和验证码构成了, 而这个密码是只有 用户自己和腾讯知道的.
    从截获的 HTTP 请求中,你是找不到这个 KEY 的,所以就更谈不上解密了.


    另外再重申一下, HTTP 协议下, 前端加密 是为了保证数据传输过程中在被第三方截获之后,不能破解(直接看到你的密码)/重放等行为的.

    拿篡改 HTTP 响应来做为否定 前端 加密必要性, 这两者完全都不是一个层次的, 没有什么可比性.
    qqmishi
        23
    qqmishi  
       2016-05-29 18:14:11 +08:00 via Android
    @xqin 反驳我之前先看看我说的最后一句。
    xqin
        24
    xqin  
       2016-05-29 18:16:23 +08:00
    @qqmishi 你一边说拦不住,一边又说加 token, 我不知道你想表达什么, 所以就 @你一下.
    muziyue
        25
    muziyue  
    OP
       2016-05-29 18:30:41 +08:00
    好了好了大伙儿别吵了,我也了解差不多了就这样吧
    qqmishi
        26
    qqmishi  
       2016-05-29 18:30:46 +08:00
    @xqin 我写的“拦不住”指的是只进行加密(比如只对密码进行 md5 加密),这种情况下每次加密结果都是一样的,和明文发送唯一的区别只是无法直接得到明文但依然可以重放。(别笑,我们学校至少有四个系统是用的这种加密方式)
    所以我后面加了一句服务端先发送 token 再进行加密。
    另外,直接上 HTTPS 省时省力,加密的话需要改写前后端的代码。不能说 HTTP 就是做不到安全传输的,但考虑下成本以及趋势,我依然建议上 HTTPS 。
    shiny
        27
    shiny  
       2016-05-29 18:39:05 +08:00
    除了随机盐值, password_hash 的另一个意义是实现了加密算法和业务逻辑的分离。
    hash 中带了加密算法类型,这样不管用什么算法, password_verify 都能验证。

    随着 PHP 版本升级,会淘汰不安全的旧算法更换为新算法,这中间甚至不需要修改代码。
    cxbig
        28
    cxbig  
       2016-05-29 18:51:06 +08:00
    这年头上 https 不是很容易么? https://letsencrypt.org
    JamesRuan
        29
    JamesRuan  
       2016-05-29 19:01:53 +08:00
    @SoloCompany 前端加密为什么没有意义?
    xqin
        30
    xqin  
       2016-05-29 19:02:04 +08:00
    @qqmishi 是的, 有条件的都建议上 HTTPS :P
    现在的 ISP 太流氓了.
    strahe
        31
    strahe  
       2016-05-29 19:11:17 +08:00
    js 本地做的东西都是欺骗自己而已.
    kookxiang
        32
    kookxiang  
       2016-05-29 19:34:41 +08:00 via Android   ❤️ 1
    password_hash 解决的是密码存储问题, https 解决的是密码传输问题
    SoloCompany
        33
    SoloCompany  
       2016-05-29 19:36:54 +08:00
    @qgy18 只嗅探不改包,那这个中间人真是太良心了,如果真的存在有不可篡改,那么因为密钥可以做到一次有效本来就可以防止重放攻击,通过 df 协议交换密钥甚至连非对称加密都不需要


    @xqin 你开心就好
    gamexg
        34
    gamexg  
       2016-05-29 20:10:43 +08:00 via Android
    你想前端加密,难道后端明文保存密码?
    或者后端保存的是和前端同一方式加密的密码?
    那样没有意义,破解者直接提交加密后的密码一样玩。
    Silicon
        35
    Silicon  
       2016-05-29 20:53:33 +08:00   ❤️ 1
    @SoloCompany 一般不会“只嗅探不改包”,而是因为“只能”……这种场景下还是没法否定前端加密的存在价值的

    但是话说回来,一次性用 HTTPS 解决问题更好啦
    Coxxs
        36
    Coxxs  
       2016-05-29 21:07:26 +08:00 via Android   ❤️ 2
    能上 https 最好,但是也不是说上就上啊。。
    大站上 https 要考虑的东西太多了,肯定是要逐步迁移的。 http 前端散列虽然可以被以各种方式截取,但也不能说没有用。
    腾讯就是个例子,前几年腾讯用的就是 http 前端加动态盐的散列,这几年改成了 RSA ,然后再逐步启用 https 。
    h4rdy
        37
    h4rdy  
       2016-05-29 21:18:22 +08:00   ❤️ 2
    楼主这样做貌似是为了防范中间人导致的密码泄露?如果是这样的话,直接 post 明文 跟 js 本地加密一下再 post 给 php 验证 都不能有效的防范中间人。直接 post 明文,中间人攻击的时候会抓到明文密码。 js 本地加密一下再 post 给 php 验证 ,虽然抓不到明文密码,但是能抓到 post 包,直接重放攻击就行了。
    maxsec
        38
    maxsec  
       2016-05-30 10:49:15 +08:00   ❤️ 3
    你们都忘记了 password_hash 的初衷。
    它不是为了解决中间人啊, JS 加密啊什么鬼的。
    他只是为了解决彩虹表+对抗 timing attack 而设定。

    以前 md5(xxxx)生成了哈希是唯一且固定的。
    现在用 password_hash(xxxx)生成的哈希理论上放大了几亿倍可能。
    然后黑客要用彩虹表来对抗 password_hash 加密的密码,基本上不可能了,只能靠穷举。
    3dwelcome
        39
    3dwelcome  
       2016-05-30 11:56:22 +08:00   ❤️ 1
    @SoloCompany "只嗅探不改包,那这个中间人真是太良心了"

    黑客在一个公共 wifi 下,的确只能嗅探,不能改包啊。大量的密码截取,都是基于海量嗅探包来提取的,又不是真的通过实时修改。

    JS 加密在目前 HTTP 网站大大多于 HTTPS 的情况下,还是有存在的意义。就如前端都痛恨 xp, 但国内的 XP 普及率还是要让写前端的同学,兼顾一下,不管内心是否愿意。

    @xqin 严重支持!
    xurubin
        40
    xurubin  
       2016-05-30 15:32:35 +08:00
    JamesRuan
        41
    JamesRuan  
       2016-05-30 17:43:28 +08:00
    @xurubin 不懂呗。
    安全其实是个无底洞,抛开应用谈安全都是耍流氓。
    JamesRuan
        42
    JamesRuan  
       2016-05-30 17:47:00 +08:00
    @maxsec password_hash 还引入了“代价”,生成 hash 需要大量的 CPU 和内存,使得暴力破解的变得非常不经济。
    param
        43
    param  
       2017-03-07 12:06:07 +08:00
    从服务器传个 token 下来浏览器,提交的时候拿 token 当做盐来算 md5 。登录成功后这个 token 便失效,这样避免重放攻击。
    但要劫持的话,可以直接给你加一段 JS ,让密码先提交到他的网站,这段 JS 甚至还能在各个网站通用,完全不需要人工劫持。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1092 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 18:59 · PVG 02:59 · LAX 10:59 · JFK 13:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.