123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- "use strict";
-
- // Crypto module import.
- const crypto = require('crypto');
-
- // Hash generation string.
- const itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-
- // To 64 bit version.
- function to64(index, count) {
- let result = '';
-
- while (--count >= 0) { // Result char count.
- result += itoa64[index & 63]; // Get corresponding char.
- index = index >> 6; // Move to next one.
- }
-
- return result;
- }
-
- // Returns salt.
- function getSalt(inputSalt) {
- let salt = '';
-
- if (inputSalt) {
- // Remove $apr1$ token and extract salt.
- salt = inputSalt.split('$')[2];
- } else {
- while(salt.length < 8) { // Random 8 chars.
- let rchIndex = Math.floor((Math.random() * 64));
- salt += itoa64[rchIndex];
- }
- }
-
- return salt;
- }
-
- // Returns password.
- function getPassword(final) {
- // Encrypted pass.
- let epass = '';
-
- epass += to64((final.charCodeAt(0) << 16) | (final.charCodeAt(6) << 8) | final.charCodeAt(12), 4);
- epass += to64((final.charCodeAt(1) << 16) | (final.charCodeAt(7) << 8) | final.charCodeAt(13), 4);
- epass += to64((final.charCodeAt(2) << 16) | (final.charCodeAt(8) << 8) | final.charCodeAt(14), 4);
- epass += to64((final.charCodeAt(3) << 16) | (final.charCodeAt(9) << 8) | final.charCodeAt(15), 4);
- epass += to64((final.charCodeAt(4) << 16) | (final.charCodeAt(10) << 8) | final.charCodeAt(5), 4);
- epass += to64(final.charCodeAt(11), 2);
-
- return epass;
- }
-
- // Exporting old style.
- module.exports = (password, salt) => {
- let magic = '';
- if (salt && salt.split('$')[1] === '1') {
- magic = '$1$';
- } else {
- magic = '$apr1$';
- }
-
- salt = getSalt(salt);
-
- let ctx = password + magic + salt;
- let final = crypto.createHash('md5').update(password + salt + password, 'ascii').digest('binary');
-
- for (let pl = password.length; pl > 0; pl -= 16) {
- ctx += final.substr(0, (pl > 16) ? 16 : pl);
- }
-
- for (let i = password.length; i; i >>= 1) {
- if (i % 2) {
- ctx += String.fromCharCode(0);
- } else {
- ctx += password.charAt(0);
- }
- }
-
- final = crypto.createHash('md5').update(ctx, 'ascii').digest('binary');
-
- // 1000 loop.
- for (let i = 0; i < 1000; ++i) {
- // Weird stuff.
- let ctxl = '';
-
- if (i % 2) {
- ctxl += password;
- } else {
- ctxl += final.substr(0, 16);
- }
-
- if (i % 3) {
- ctxl += salt;
- }
-
- if (i % 7) {
- ctxl += password;
- }
-
- if (i % 2) {
- ctxl += final.substr(0, 16);
- } else {
- ctxl += password;
- }
-
- // Final assignment after each loop.
- final = crypto.createHash('md5').update(ctxl, 'ascii').digest('binary');
- }
-
- return magic + salt + '$' + getPassword(final);
- };
|