NodeJS 中的 RabbitMQ 密码散列
RabbitMQ password hashing in NodeJS
我在 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);
输出: 节点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));
输出: 节点password.js测试>>Mu+/ve+/vWnvv73vv71C77+977+9HBTvv73vv73vv73ImW/vv70kJ++/vUHvv71k77+977+9TO+/ve+/ve+/vRt4Uu+/vVU=
任何人都可以帮助正确实施吗?
你可以或多或少地移植到 NodeJS 1:1:
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
。您需要用您的密码替换密码。
请注意,即使密码相同,您也无法直接比较 Python 和 NodeJS 代码的结果,因为 random 盐。
因此,带有UTF-8编码盐1234
的注释掉的行可用于产生与Python代码进行比较的结果:MTIzNNcAIpZVAOz2It9VMePU/k4wequLpsQVl+aYDdJa6y9r
您的第一个实施中的问题是,除其他外,Python 代码中未应用 PBKDF2 的使用。
第二个实现更接近实际解决方案。一个问题是散列没有考虑要散列的数据。
另一个缺陷是字符串的使用,其中一些操作隐式应用 UTF-8 编码,这会破坏(任意二进制)数据。为防止这种情况,必须使用 binary
作为编码而不是 UTF-8。仅仅因为可能的编码问题,这里使用字符串的实现不如使用缓冲区那么健壮。
我在 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);
输出: 节点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));
输出: 节点password.js测试>>Mu+/ve+/vWnvv73vv71C77+977+9HBTvv73vv73vv73ImW/vv70kJ++/vUHvv71k77+977+9TO+/ve+/ve+/vRt4Uu+/vVU=
任何人都可以帮助正确实施吗?
你可以或多或少地移植到 NodeJS 1:1:
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
。您需要用您的密码替换密码。
请注意,即使密码相同,您也无法直接比较 Python 和 NodeJS 代码的结果,因为 random 盐。
因此,带有UTF-8编码盐1234
的注释掉的行可用于产生与Python代码进行比较的结果:MTIzNNcAIpZVAOz2It9VMePU/k4wequLpsQVl+aYDdJa6y9r
您的第一个实施中的问题是,除其他外,Python 代码中未应用 PBKDF2 的使用。
第二个实现更接近实际解决方案。一个问题是散列没有考虑要散列的数据。
另一个缺陷是字符串的使用,其中一些操作隐式应用 UTF-8 编码,这会破坏(任意二进制)数据。为防止这种情况,必须使用 binary
作为编码而不是 UTF-8。仅仅因为可能的编码问题,这里使用字符串的实现不如使用缓冲区那么健壮。