I'm attempting to port a Python module to NodeJS for various reasons and I've run into a bit of a stumbling block. I'm having difficulties with getting a proper MD5 digest (and yes, I'm aware of the security issues of MD5 but it's either that or clear text for the app that I'm connecting to).
Here's a simplified working Python version:
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
Which outputs the following:
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
Now, for my JavaScript code the closest I've been able to come is this code:
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);
And that code outputs the following:
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
I'm thinking that the issue is with the string conversion from the Buffer (digest variable) but I've not found a way to correct this. I've even tried the pulling the relevant code from here (starting line 178) but that gives me yet another hexdigest (and from what I've read, the "binary" encoding is deprecated) using the following code:
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);
This prints out:
hexdigest: 5deef0b84014693b745ea40b047f4ae8
First question: Does anyone know why this is happening and/or know how to get it working?
Second question: Is there a better way to port the Python code to NodeJS?
I'm currently using NodeJS 7.6.0. My thanks to anyone who can help shed some light on this, I've spent way to long beating my head on the keyboard.
UPDATE: 2017/04/05
After sleeping on it... Turns out that I do need to use the .digest('binary') to get the digest correct. When comparing the fullsecret character codes the were different between Python and JS if I don't use the .digest('binary'). However, now that the fullsecret strings contain identical character codes from both Python and JS, something is wrong with the last hexdigest portion in JS... Code and output above has been modified to reflect the changes.