【问题标题】:RabbitMQ password hashing in NodeJSNodeJS 中的 RabbitMQ 密码散列
【发布时间】:2021-10-06 13:25:52
【问题描述】:

我正在使用带有 Docker 的 RabbitMQ。我想直接在definitions.json 文件中更新配置。用户应该使用rabbit_password_hashing_sha256 散列算法将密码存储在那里。我找到了一个有用的 Python 脚本来散列密码,但我无法在 NodeJS 中使用 Crypto 库重现它的逻辑。

Python 脚本:

#!/usr/bin/env python3

# RabbitMQ password hashing algorith as laid out in:
# http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-May/012765.html

from __future__ import print_function
import base64
import os
import hashlib
import struct
import sys

# The plain password to encode
password = sys.argv[1]

# Generate a random 32 bit salt
salt = os.urandom(4)

# Concatenate with the UTF-8 representation of plaintext password
tmp0 = salt + password.encode('utf-8')

# Take the SHA256 hash and get the bytes back
tmp1 = hashlib.sha256(tmp0).digest()

# Concatenate the salt again
salted_hash = salt + tmp1

# Convert to base64 encoding
pass_hash = base64.b64encode(salted_hash)

# Print to the console (stdout)
print(pass_hash.decode("utf-8"))

输出: python hash-password.py test >> t7+JG/ovWbTd9lfrYrPXdFhNZLcO+y56x4z0d8S2OutE6XTE

第一次实施失败:

const crypto = require('crypto');

this.password = process.argv[2];

this.salt = crypto.randomBytes(16).toString('hex');

this.password_hash = crypto.pbkdf2Sync(this.password.trim(), this.salt, 1000, 24, `sha256`).toString(`hex`);

console.log(this.password_hash);

输出: node password.js 测试 >> 7611058fb147f5e7a0faab8a806f56f047c1a091d8355544

在NodeJS中无法复现,所以收集了stdout子进程执行结果,不太优雅。

第二次实施失败:

const crypto = require('crypto');
const utf8 = require('utf8');

this.password = process.argv[2];

this.salt = crypto.randomBytes(4);

this.tmp0 = this.salt + utf8.encode(this.password);

this.tmp1 = crypto.createHash(`sha256`).digest();

this.salted_hash = this.salt + this.tmp1;

this.pass_hash = Buffer.from(this.salted_hash).toString('base64');

console.log(utf8.decode(this.pass_hash));

输出: node password.js 测试 >> Mu+/ve+/vWnvv73vv71C77+977+9HBTvv73vv73vv73ImW/vv70kJ++/vUHvv71k77+977+9TO+/ve+/ve+/vRt4Uu+/vVU=

任何人都可以帮助正确实施吗?

【问题讨论】:

  • 请发布您最近的 NodeJS 代码并描述问题。
  • 请同时添加示例密码、您从 python 代码中获得的哈希值以及您的 node.js 代码中的结果。
  • 用代码和输出扩展了问题。

标签: python node.js hash rabbitmq cryptojs


【解决方案1】:

您可以或多或少地 1:1 移植到 NodeJS:

var crypto = require('crypto') 

// The plain password to encode
var password = Buffer.from('my passphrase', 'utf8') // sample password

//  Generate a random 32 bit salt
var salt = crypto.randomBytes(4);
//var salt = Buffer.from('1234', 'utf8'); // for testing, gives pass_hash = MTIzNNcAIpZVAOz2It9VMePU/k4wequLpsQVl+aYDdJa6y9r  

// Concatenate with the UTF-8 representation of plaintext password
var tmp0 = Buffer.concat([salt, password])

// Take the SHA256 hash and get the bytes back
var tmp1 = crypto.createHash('sha256').update(tmp0).digest()

// Concatenate the salt again
var salted_hash = Buffer.concat([salt, tmp1])

// Convert to base64 encoding
pass_hash = salted_hash.toString('base64')

// Print to the console (stdout)
console.log(pass_hash)

上面的代码使用密码my passphrase作为示例。您需要将密码替换为您的密码。

请注意,即使密码相同,由于 随机 salt,您也无法直接比较 Python 和 NodeJS 代码的结果。
因此,注释掉的带有 UTF-8 编码盐 1234 的行可用于生成与 Python 代码比较的结果:MTIzNNcAIpZVAOz2It9VMePU/k4wequLpsQVl+aYDdJa6y9r


您的第一个实现中的问题之一是使用了 PBKDF2,它未应用于 Python 代码。

第二种实现更接近实际的解决方案。一个问题是散列没有考虑要散列的数据。
另一个缺陷是使用字符串,其中一些操作隐式应用 UTF-8 编码,这会破坏(任意二进制)数据。为了防止这种情况,binary 必须用作编码而不是 UTF-8。仅仅因为可能的编码问题,这里使用字符串的实现不如使用缓冲区健壮。

【讨论】:

  • 当然,最终结果总是下来(因为随机盐),再次在使用方面我可以确认密码哈希生成器的正确性,登录到RabbitMQ管理界面是成功的新密码。用作缓冲区是可以理解的,感谢您的解决方案和详细的理由。
猜你喜欢
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
  • 2019-02-15
  • 2017-06-26
  • 2016-03-23
  • 1970-01-01
  • 2012-12-10
相关资源
最近更新 更多