V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cevincheung
V2EX  ›  问与答

PHP 是不是也太“任性”了点…… 关于 bcrypt

  •  
  •   cevincheung · 2015-09-04 09:27:51 +08:00 · 4636 次点击
    这是一个创建于 3399 天前的主题,其中的信息可能已经有所发展或是发生改变。

    password_hash第二个参数PASSWORD_BCRYPTPASSWORD_DEFAULT分明就是同一个参数……

    还有。 bcrypt 计算出来的为啥是$2y 开头的? python 中 bcrypt 计算出来的都是$2a 开头的啊,为啥? php 生成的密码到 python 里还能用么?

    17 条回复    2017-12-21 16:08:36 +08:00
    haiyang416
        1
    haiyang416  
       2015-09-04 09:41:39 +08:00
    直接用估计是不行的了, PHP 的 Base64 字符集都和标准的不同。
    haiyang416
        2
    haiyang416  
       2015-09-04 10:00:01 +08:00
    @haiyang416 先收回这句话,搜了一圈没找到出处了。
    caixiexin
        3
    caixiexin  
       2015-09-04 10:00:09 +08:00
    模块化算法 BCrypt 的格式由

    $2$ , $2a$ or $2y$ 标识的哈希算法和格式。
    两个数字参数表示的成本值, 后面跟着 $
    一个字符长的 53 base-64-encoded ( 它们使用字母值 . , / , 0 – 9 , A – Z , a – z 不同的 标准 Base 64 Encoding 字母组成的) :
    仅 22 字符的盐( 有效地 128 ) 132 解码后的位位
    31 加密的字符输出( 有效地只 184 ) 186 解码后的位位
    因此总长度是 59 或者 60 字节分别。
    -----------------------
    以前查 bcrypt 资料看到的,可能 python 和 php 实现 bcrypt 哈希算法略有不同。具体你可以找找 bcrypt 的详细说明:)
    haiyang416
        4
    haiyang416  
       2015-09-04 10:06:38 +08:00
    breeswish
        5
    breeswish  
       2015-09-04 12:20:09 +08:00
    固定 cost 试试
    cevincheung
        6
    cevincheung  
    OP
       2015-09-04 12:45:44 +08:00
    @breeswish 跟 cost 没关系, cost 是第二部分的值比如$2y$cost$、$2y$07$
    cevincheung
        7
    cevincheung  
    OP
       2015-09-04 12:47:28 +08:00
    @caixiexin 所以这个算法不是统一的么?是不是可以理解成 php 的 bcrypt 未“完全”实现?
    skydiver
        8
    skydiver  
       2015-09-04 12:50:00 +08:00
    CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt () to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithmeter and must be in range 04-31, values outside this range will cause crypt () to fail. Versions of PHP before 5.3.7 only support "$2a$" as the salt prefix: PHP 5.3.7 introduced the new prefixes to fix a security weakness in the Blowfish implementation. Please refer to » this document for full details of the security fix, but to summarise, developers targeting only PHP 5.3.7 and later should use "$2y$" in preference to "$2a$".

    这里有说明 http://php.net/manual/en/function.crypt.php
    cevincheung
        9
    cevincheung  
    OP
       2015-09-04 12:51:55 +08:00
    @skydiver 所以潜台词是$2a 可能存在不安全的潜在风险?
    breeswish
        10
    breeswish  
       2015-09-04 12:52:40 +08:00   ❤️ 1
    @cevincheung 抱歉没仔细看 :-) 确实是算法不一样,具体解释在这里

    http://security.stackexchange.com/questions/20541/insecure-versions-of-crypt-hashes/20543#20543

    Python 下可以用 passlib.hash.bcrypt 生成 2y 的 bcrypt : https://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html
    skydiver
        11
    skydiver  
       2015-09-04 12:52:49 +08:00
    @cevincheung 看着是这个意思
    laoyuan
        12
    laoyuan  
       2015-09-04 16:27:35 +08:00   ❤️ 1
    毕竟宇宙第一
    raincious
        13
    raincious  
       2015-09-05 12:17:22 +08:00
    关于 2a 和 2y 前缀的问题,其实这个跟你用的 Salt 有关系,如果你的 Salt 是 2a 开头的,那么 crypt 就会用 2a 算法运算结果然后得到一个 2a 开头的序列, 2y 也同理。

    password_hash 默认的 Salt 给的就是 2y 前缀,所以自然结果也就是 2y 开头的。
    cevincheung
        14
    cevincheung  
    OP
       2015-09-05 15:11:44 +08:00
    @raincious

    这样的
    var_dump (PASSWORD_DEFAULT )结果是 integer 1
    var_dump (PASSWORD_BCRYPT )结果是 integer 1

    那给这两个配置有毛用?
    raincious
        15
    raincious  
       2015-09-05 15:32:07 +08:00
    @raincious

    你可以理解成 PASSWORD_DEFAULT 就是选择一个默认值,而默认值是 PASSWORD_BCRYPT 啊。( *手动笑哭*

    要是有多个常数的话,可能就不会有这种感觉了,

    比如选项是:
    PASSWORD_ASMILEPT
    PASSWORD_BCRYPT
    PASSWORD_CLAUGHPT
    PASSWORD_DRAGEPT
    PASSWORD_ENVYPT
    PASSWORD_FROWNPT
    PASSWORD_GIGGLEPT

    默认值 PASSWORD_DEFAULT 是 PASSWORD_BCRYPT
    chaegumi
        16
    chaegumi  
       2016-08-11 14:29:12 +08:00
    最搞笑的是现在要接入 jasig cas ,别人是 2a php 是 2y ,接入 jasig cas 的密码验证还得自己写个 2y 的来匹配
    verytoex
        17
    verytoex  
       2017-12-21 16:08:36 +08:00
    我测试过,用 spring.security 来校验 PHP 创建的 hash,只要把 2y 替换成 2a 就能校验通过了。
    PHP 兼容 2a 和 2y,两个都支持。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5725 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:59 · PVG 10:59 · LAX 18:59 · JFK 21:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.