在 Node/Express 服务器上复制 Rails/AuthLogic Scrypt 哈希比较

问题描述 投票:0回答:1

我正在将旧的 ruby-on-rails 站点迁移到 node/express/react/redux,并且在验证用户现有密码方面遇到了困难。 该网站目前使用 AuthLogic(scrypt) 进行身份验证/密码哈希处理,一些较旧的帐户密码仍使用 sha512 AuthLogic 算法进行哈希处理。

我一生都无法弄清楚如何在 Node.js 中复制 authLogic 的 scrypt 算法。 我已经审查了 AuthLogic 的 ruby 源咒语和底层 scrypt 包,这给了我一些线索。

我正在使用最新版本的 npm scrypt 软件包(我已经尝试了其他一些软件包,没有明显的差异)。

存储的哈希如下所示:

400$8$1d$3fbb0d3688d9da6d$5dd919ace6bdf946d48946e9dd61f0afc5116986433633e24e58809c12b5ce9a

数据库还存储了唯一的盐参数:

fbMQa7EhFp5tdOhNsT

根据 scrypt gem 源,看起来 $ 分隔的部分是成本因素和盐:

n, r, p = args[0].split('$').map{ |x| x.to_i(16) }
来自 Scrypt gem scrypt.rb 源。

根据代码,看起来前三个 $ 分隔位是 scrypt 的“成本”因素,最后一个是盐。 我不知道为什么这个盐与数据库中存储的盐不同,或者我应该如何插入它们。这促使我尝试:

    const n = parseInt("400", 16)
    const r = parseInt("8", 16);
    const p = parseInt("1d", 16)
    const result = scrypt.hashSync("[my password]",{"N":n,"r":r,"p":p}, 32, 3fbb0d3688d9da6d);

其结果是与数据库存储不同的散列,但至少是正确的长度。

80e302f9f8942ec9d81fe217c03730b5b8256b22cd91ad2dd2a448ec588ec390

所以我尝试比较一下:

     const comparision = scrypt.verifyKdfSync(
    "5dd919ace6bdf946d48946e9dd61f0afc5116986433633e24e58809c12b5ce9a", 
    "[mypassword]"); 

但这失败了,告诉我数据不是加密哈希数据。 我尝试在散列中添加各种成本因子和盐(带或不带 $ 分隔符),但无济于事。 我尝试将哈希值转换为缓冲区对象,但也无济于事。使用上述选项尝试 kdfSync 也失败(计算派生密钥时出错)。在线工具也不会将存储的哈希识别为 scrypt 哈希。

帮助我红宝石魔术师(或任何其他有密码学能力的人),你是我唯一的希望。

javascript ruby-on-rails node.js authlogic scrypt
1个回答
0
投票

我最近遇到了这个问题,并发现 AuthLogic + Scrypt 的组合本质上是对密码进行双重加盐。 AuthLogic 创建自己的盐,存储在

password_salt
中,在调用 Scrypt 之前将其附加到用户的密码中。

因此,要直接使用 Scrypt(在 Ruby 中)验证用户的密码,您需要执行以下操作:

SCrypt::Password.new(user.crypted_password) == "[my_password]"+password_salt

对于里德来说,这意味着他们应该尝试:

const n = parseInt("400", 16)
const r = parseInt("8", 16);
const p = parseInt("1d", 16)
const result = scrypt.hashSync("[my password]"+"fbMQa7EhFp5tdOhNsT",{"N":n,"r":r,"p":p}, 32, 3fbb0d3688d9da6d);
© www.soinside.com 2019 - 2024. All rights reserved.