Tuesday, 4 April 2017

Issues trying to replicate a Python DIGEST-MD5 hashing function in NodeJS

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 '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]
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();
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('hexdigest: ' + hexdigest);

And that code 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]
hexdigest: 2e78cfb69cd1ee1c7199c0c720ecf6e7

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.



via Matt W

No comments:

Post a Comment