JS Twin-Bcrypt盐模式

时间:2015-02-23 12:51:27

标签: javascript regex salt bcrypt

我一直在探索 Twin-Bcrypt JavaScript库,发现了一件奇怪的事情。有一次,我在服务器端使用PHP base64_encode(openssl_random_pseudo_bytes(16))制作了自己的盐,并在TwinBcrypt.hash()函数中使用它,由于库中的常规模式不匹配,因此响应盐无效。所以,模式是:

var SALT_PATTERN = /^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu]/;

我的盐看起来很好,除了一件事 - 这到底是什么 - [.Oeu]

我的第一个问题是,为什么他们希望salt以 dot O e 结束û?据我所知openssl_random_pseudo_bytes()生成安全 CSPRNG ,但由于模式,JS库不想接受它。

第二个问题 - 盐是否有任何安全理由以/[.Oeu]/模式结束?

我会非常感谢任何帮助,因为没有太多关于它的信息。

1 个答案:

答案 0 :(得分:4)

我不太了解bcrypt,但看来Twin-Bcrypt希望salt参数包含完整的类型标记(2a / 2y / {{1 }}),cost参数,实际的加密盐值。 (我相信这样做是为了满足其他库的期望。)加密盐值只是2x参数字符串的最后22个字符,表示128位值。

要真正解决您的问题,您需要做两件事:

  1. 使用salt为您的盐添加前缀,使其具有类型标记和费用参数。

  2. 将您的PHP $2y$10$结果映射到bcrypt的非标准base64值。作为参考,值为:

    base64_encode

    如果您只想将标准base64转换为brcypt-base64字符串,则可以将所有Standard: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ bcrypt: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 替换为+,但这将导致不同的值(因为标准. }是+,而62.,所有其他值也都是偏移量)。如果您想要一个与原始字符串值相同的brypt字符串,则需要用其bcrypt等效字符替换每个字符。

    您可能还需要从标准字符串中删除尾随0(如果存在)。


  3. 额外信息:为什么盐必须以=结束?

    bcrypt中的盐是128位。每个base64字符传递6位信息。这意味着21个base64字符可以均匀地传输126位。最后的2位必须以最后的第22个字符编码。由于该字符仅由2位定义,因此它只能有4个可能的值。

    当我们检查brypt的base64字符池时,我们看到:

    [.Oeu]

    从零开始计算,我们看到这些值出现在标记处:

    ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
    

    所以最后两位是设置最终字符的高端位。