Javascript JS孪晶Bcrypt盐型

Javascript JS孪晶Bcrypt盐型,javascript,regex,salt,bcrypt,Javascript,Regex,Salt,Bcrypt,我一直在探索Twin BcryptJavaScript库,发现了一个奇怪的东西。有一次,我在服务器端用PHPbase64\u编码(openssl\u random\u pseudo\u bytes(16))制作了自己的salt,并在TwinBcrypt.hash()函数中使用了它,该函数响应salt无效,因为库中的规则模式不匹配。因此,模式是: var SALT_PATTERN = /^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.

我一直在探索Twin BcryptJavaScript库,发现了一个奇怪的东西。有一次,我在服务器端用PHP
base64\u编码(openssl\u random\u pseudo\u bytes(16))
制作了自己的salt,并在
TwinBcrypt.hash()
函数中使用了它,该函数响应salt无效,因为库中的规则模式不匹配。因此,模式是:

var SALT_PATTERN = /^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu]/;
它看起来很适合我的盐,除了一件事-这到底是什么-
[.Oeu]

我的第一个问题是,为什么他们期望盐以点,O,e,u结尾?据我所知,
openssl\u random\u pseudo\u bytes()
生成安全的CSPRNG,但由于模式的原因,JS库不想接受它

第二个问题-salt以
/[.Oeu]/
模式结尾是否有任何安全原因


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

我对bcrypt不太了解,但Twin bcrypt似乎希望
salt
参数包含完整的类型标记(
2a
/
2y
/
2x
)、成本参数和实际的加密salt值。(我相信这样做是为了满足其他库的期望。)加密salt值只是
salt
参数字符串的最后22个字符,它表示128位的值

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

  • 在salt前面加上
    $2y$10$
    ,这样它就有一个类型标签和一个成本参数

  • 将PHP
    base64\u encode
    结果映射到bcrypt的非标准base64值。参考值如下:

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

    您可能还需要从标准字符串中删除尾随的
    =
    ,如果有的话


  • 额外信息:为什么盐必须以
    [.Oeu]
    结尾?

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

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

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

    . => 0  = 000000
    O => 16 = 010000 
    e => 32 = 100000
    u => 48 = 110000
    

    因此,最后两位是设置最后一个字符的高端位。

    这应该添加到Wiki中。非常感谢你!