reformatted md5

This commit is contained in:
Andris Reinman 2018-09-11 16:03:54 +03:00
parent 202d8d29a4
commit 8789cce45f

View file

@ -1,140 +1,200 @@
/*- /* eslint no-bitwise: 0*/
* Copyright (c) 2003 Poul-Henning Kamp 'use strict';
* All rights reserved.
* /*-
* Converted to JavaScript / node.js and modified by Dominik Deobald / Interdose.com * Copyright (c) 2003 Poul-Henning Kamp
* * All rights reserved.
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions * Converted to JavaScript / node.js and modified by Dominik Deobald / Interdose.com
* are met: *
* 1. Redistributions of source code must retain the above copyright * Redistribution and use in source and binary forms, with or without
* notice, this list of conditions and the following disclaimer. * modification, are permitted provided that the following conditions
* 2. Redistributions in binary form must reproduce the above copyright * are met:
* notice, this list of conditions and the following disclaimer in the * 1. Redistributions of source code must retain the above copyright
* documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* * 2. Redistributions in binary form must reproduce the above copyright
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * notice, this list of conditions and the following disclaimer in the
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * documentation and/or other materials provided with the distribution.
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* SUCH DAMAGE. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*/ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
var crypto = require('crypto'); * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
// http://code.activestate.com/recipes/325204-passwd-file-compatible-1-md5-crypt/ */
// http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libcrypt/crypt.c?rev=1.2&content-type=text/plain let crypto = require('crypto');
// http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libcrypt/crypt-md5.c
exports.cryptMD5 = function(pw, salt) { // http://code.activestate.com/recipes/325204-passwd-file-compatible-1-md5-crypt/
var magic = '$1$'; // http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libcrypt/crypt.c?rev=1.2&content-type=text/plain
var fin; // http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libcrypt/crypt-md5.c
var sp = salt || generateSalt(8); exports.cryptMD5 = function(pw, salt) {
let magic = '$1$';
var ctx = crypto.createHash('md5'); let fin;
let sp = salt || generateSalt(8);
// The password first, since that is what is most unknown
// Then our magic string let ctx = crypto.createHash('md5');
// Then the raw salt
ctx.update(pw + magic + sp); // The password first, since that is what is most unknown
// Then our magic string
// Then just as many characters of the MD5(pw,sp,pw) // Then the raw salt
var ctx1 = crypto.createHash('md5'); ctx.update(pw + magic + sp);
ctx1.update(pw);
ctx1.update(sp); // Then just as many characters of the MD5(pw,sp,pw)
ctx1.update(pw); let ctx1 = crypto.createHash('md5');
var fin = ctx1.digest("binary"); ctx1.update(pw);
ctx1.update(sp);
for(var i = 0; i < pw.length ; i++) { ctx1.update(pw);
ctx.update(fin.substr(i % 16, 1),'binary'); fin = ctx1.digest('binary');
}
for (let i = 0; i < pw.length; i++) {
// Then something really weird... ctx.update(fin.substr(i % 16, 1), 'binary');
}
// Also really broken, as far as I can tell. -m
// Agreed ;) -dd // Then something really weird...
for (var i = pw.length; i; i >>= 1) { // Also really broken, as far as I can tell. -m
ctx.update ( (i & 1) ? "\x00" : pw[0] ); // Agreed ;) -dd
}
for (let i = pw.length; i; i >>= 1) {
fin = ctx.digest("binary"); ctx.update(i & 1 ? '\x00' : pw[0]);
}
// and now, just to make sure things don't run too fast fin = ctx.digest('binary');
for (var i = 0; i < 1000; i++) {
var ctx1 = crypto.createHash('md5'); // and now, just to make sure things don't run too fast
for (let i = 0; i < 1000; i++) {
if (i & 1) { let ctx1 = crypto.createHash('md5');
ctx1.update(pw);
} else { if (i & 1) {
ctx1.update(fin,'binary'); ctx1.update(pw);
} } else {
ctx1.update(fin, 'binary');
if (i % 3) { }
ctx1.update(sp);
} if (i % 3) {
ctx1.update(sp);
if (i % 7) { }
ctx1.update(pw);
} if (i % 7) {
ctx1.update(pw);
if (i & 1) { }
ctx1.update(fin,'binary');
} else { if (i & 1) {
ctx1.update(pw); ctx1.update(fin, 'binary');
} } else {
ctx1.update(pw);
fin = ctx1.digest("binary") }
}
fin = ctx1.digest('binary');
return magic + sp + '$' + to64(fin); }
} return magic + sp + '$' + to64(fin);
};
function to64(data) { function to64(data) {
// This is the bit that uses to64() in the original code. // This is the bit that uses to64() in the original code.
var itoa64 = ['.','/','0','1','2','3','4','5','6','7','8','9','A','B','C','D', let itoa64 = [
'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T', '.',
'U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j', '/',
'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; '0',
'1',
var rearranged = ''; '2',
'3',
var opt = [[0, 6, 12], [1, 7, 13], [2, 8, 14], [3, 9, 15], [4, 10, 5]]; '4',
'5',
for (var p in opt) { '6',
var l = data.charCodeAt( opt[p][0] ) << 16 | data.charCodeAt( opt[p][1] ) << 8 | data.charCodeAt( opt[p][2] ); '7',
'8',
for (var i = 0; i < 4; i++) { '9',
rearranged += itoa64[l & 0x3f]; l >>= 6 'A',
} 'B',
} 'C',
'D',
var l = data.charCodeAt(11); 'E',
for (var i = 0; i < 2; i++) { 'F',
rearranged += itoa64[l & 0x3f]; l >>= 6 'G',
} 'H',
'I',
return rearranged; 'J',
} 'K',
'L',
'M',
var SaltLength = 8; 'N',
'O',
function generateSalt(len) { 'P',
var set = '0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ', 'Q',
setLen = set.length, 'R',
salt = ''; 'S',
for (var i = 0; i < len; i++) { 'T',
var p = Math.floor(Math.random() * setLen); 'U',
salt += set[p]; 'V',
} 'W',
return salt; 'X',
} 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
];
let rearranged = '';
let opt = [[0, 6, 12], [1, 7, 13], [2, 8, 14], [3, 9, 15], [4, 10, 5]];
for (let p in opt) {
let l = (data.charCodeAt(opt[p][0]) << 16) | (data.charCodeAt(opt[p][1]) << 8) | data.charCodeAt(opt[p][2]);
for (let i = 0; i < 4; i++) {
rearranged += itoa64[l & 0x3f];
l >>= 6;
}
}
let l = data.charCodeAt(11);
for (let i = 0; i < 2; i++) {
rearranged += itoa64[l & 0x3f];
l >>= 6;
}
return rearranged;
}
function generateSalt(len) {
let set = '0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ',
setLen = set.length,
salt = '';
for (let i = 0; i < len; i++) {
let p = Math.floor(Math.random() * setLen);
salt += set[p];
}
return salt;
}