【问题标题】:Issues trying to replicate a Python DIGEST-MD5 hashing function in NodeJS尝试在 NodeJS 中复制 Python DIGEST-MD5 散列函数的问题
【发布时间】:2017-08-30 08:09:39
【问题描述】:

出于各种原因,我试图将 Python 模块移植到 NodeJS,但遇到了一些绊脚石。我在获取正确的 MD5 摘要时遇到了困难(是的,我知道 MD5 的安全问题,但它是我要连接的应用程序的那个或明文)。

这是一个简化的工作 Python 版本:

from hashlib import md5

username = 'username'
password = 'password'
nonce = '241d4105fe8f60cef84524f6'
cnonce = '7db4c8275fb38f94774c1fe7'

secret = '%s:my realm:%s' % (username, password)
digest = md5(secret).digest()
fullsecret = ':'.join([digest, nonce, cnonce])
hexdigest = md5(fullsecret).hexdigest()

print 'digest: %s' % digest
print 'digest char codes: ' + str([ord(c) for c in digest])
print 'fullsecret: %s' % fullsecret
print 'fullsecret char codes:\n  ' + str([ord(c) for c in fullsecret])
print 'hexdigest: %s' % hexdigest

输出如下:

digest: ȣ�P��r�l������
digest char codes: [200, 163, 248, 16, 80, 182, 139, 114, 188, 108, 184, 141, 136, 168, 130, 198]
fullsecret: ȣ�P��r�l������:241d4105fe8f60cef84524f6:7db4c8275fb38f94774c1fe7
fullsecret char codes:
  [200, 163, 248, 16, 80, 182, 139, 114, 188, 108, 184, 141, 136, 168, 130, 198, 58, 50, 52, 49, 100, 52, 49, 48, 53, 102, 101, 56, 102, 54, 48, 99, 101, 102, 56, 52, 53, 50, 52, 102, 54, 58, 55, 100, 98, 52, 99, 56, 50, 55, 53, 102, 98, 51, 56, 102, 57, 52, 55, 55, 52, 99, 49, 102, 101, 55]
hexdigest: 6f9d2b47bd232495c2f765ce5a5d8ba7

现在,对于我的 JavaScript 代码,我能找到的最接近的就是这段代码:

var crypto = require('crypto');

var username = 'username';
var password = 'password';
var nonce = '241d4105fe8f60cef84524f6';
var cnonce = '7db4c8275fb38f94774c1fe7';

var secret = username + ':my realm:' + password;
var digest = crypto.createHash('md5').update(secret).digest('binary');
var fullsecret = [digest, nonce, cnonce].join(':');
var hexdigest = crypto.createHash('md5').update(fullsecret).digest('hex');

console.log('digest: ' + digest);
// console.log('digest char codes: [' + digest.map((x) => { return x; }).join(', ') + ']');
console.log('fullsecret: ' + fullsecret);
console.log('fullsecret char codes:\n  [' + fullsecret.split('').map((x) => { return x.charCodeAt() }).join(', ') + ']');
console.log('hexdigest: ' + hexdigest);

该代码输出以下内容:

digest: ȣ�P��r�l������
fullsecret: È£øP¶r¼l¸¨Æ:241d4105fe8f60cef84524f6:7db4c8275fb38f94774c1fe7
fullsecret char codes:
  [200, 163, 248, 16, 80, 182, 139, 114, 188, 108, 184, 141, 136, 168, 130, 198, 58, 50, 52, 49, 100, 52, 49, 48, 53, 102, 101, 56, 102, 54, 48, 99, 101, 102, 56, 52, 53, 50, 52, 102, 54, 58, 55, 100, 98, 52, 99, 56, 50, 55, 53, 102, 98, 51, 56, 102, 57, 52, 55, 55, 52, 99, 49, 102, 101, 55]
hexdigest: 5deef0b84014693b745ea40b047f4ae8

我认为问题出在缓冲区(摘要变量)的字符串转换上,但我还没有找到解决此问题的方法。我什至尝试使用以下代码从here (从第 178 行开始)提取相关代码,但这又给了我另一个 hexdigest(从我读过的内容来看,不推荐使用“二进制”编码):

function md5(str, encoding){
    return crypto
      .createHash('md5')
      .update(str)
      .digest(encoding || 'hex');
}

var hexdigest = md5(md5(secret, 'binary') + ':' + nonce + ':' + cnonce);
console.log('hexdigest: ' + hexdigest);

打印出来:

hexdigest: 5deef0b84014693b745ea40b047f4ae8

第一个问题:有谁知道为什么会这样和/或知道如何让它发挥作用?

第二个问题:有没有更好的方法将 Python 代码移植到 NodeJS?

我目前使用的是 NodeJS 7.6.0。感谢任何可以帮助阐明这一点的人,我已经花了很长时间在键盘上敲打我的头。

更新:2017/04/05

在上面睡觉之后......原来我确实需要使用 .digest('binary') 来获得正确的摘要。在比较完全机密字符代码时,如果我不使用 .digest('binary'),Python 和 JS 之间的代码会有所不同。但是,既然完全机密字符串包含来自 Python 和 JS 的 相同 字符代码,那么 JS 中的最后一个 hexdigest 部分出了点问题......上面的代码和输出已被修改以反映这些变化。

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    最好避免将字节表示为字符串。节点有 Buffer 类型:

    var crypto = require('crypto');
    
    var username = 'username';
    var password = 'password';
    var nonce = Buffer.from('241d4105fe8f60cef84524f6');
    var cnonce = Buffer.from('7db4c8275fb38f94774c1fe7');
    
    var secret = username + ':my realm:' + password;
    var digest = crypto.createHash('md5').update(secret).digest();
    var fullsecret = Buffer.concat([digest, Buffer.from(':'), nonce, Buffer.from(':'), cnonce]);
    var hexdigest = crypto.createHash('md5').update(fullsecret).digest('hex');
    
    console.log('digest: ' + digest);
    console.log('digest char codes: [' + digest.join(', ') + ']');
    console.log('fullsecret: ' + fullsecret);
    console.log('fullsecret char codes:\n  [' + fullsecret.join(', ') + ']');
    console.log('hexdigest: ' + hexdigest);
    

    注意Buffer.from()s 将 ASCII 字符串编码为字节,Buffer.concat 用于连接缓冲区,.digest() 没有编码参数以生成缓冲区而不是字符串。

    【讨论】:

    • 谢谢!有一次,我将 nonce 和 cnonce 作为缓冲区,但我错过了为每个冒号创建缓冲区......这就像一个魅力。
    猜你喜欢
    • 2021-06-29
    • 2017-02-26
    • 2019-01-10
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    相关资源
    最近更新 更多