Password encryption algorithm throws an exception when converting to JS from PHP

Below is the password hashing algorithm that I have to use for the control panel that I create. The original function is in PHP, but I rewrite it for use with Node.js in JavaScript.

Everything seems fine, but then I call in fModand get a failure:

RangeError: toFixed() digits argument must be between 0 and 20

The function fModworks correctly, but with different values. I highlighted the line in fModwhich throws an exception.

The correct password hash should be:

0x31c7296631df873d0891b7b77ae0c6c6

the code:

// JavaScript Version
var pass = "Cake99";

console.log(pCrypt2(pass));

function pCrypt2(plain) {

    var array_mul = [213119, 213247, 213203, 213821];
    var array_add = [2529077, 2529089, 2529589, 2529997];
    var dst = Array.apply(null, new Array(16)).map(Number.prototype.valueOf,0);
    var key = Array.apply(null, new Array(16)).map(Number.prototype.valueOf,0);

    for (var i = 0; i < plain.length; i++ ) {
        dst[i] = key[i] = ord(plain.substr(i, 1));
    }

    var val = [];
    for (var i = 0; i <= 3; i++ ) {
        val[i] = fmod((key[i * 4 + 0] + key[i * 4 + 1] * 0x100 + key[i * 4 + 2] * 0x10000 + key[i * 4 + 3] * 0x1000000) * array_mul[i] + array_add[i], 4294967296 );
    }

    for (i = 0; i <= 3; i++ ) {
        key[i * 4 + 0] = val[i] & 0xff;
        key[i * 4 + 1] = val[i] / 0x100 & 0xff;
        key[i * 4 + 2] = val[i] / 0x10000 & 0xff;
        key[i * 4 + 3] = val[i] / 0x1000000 & 0xff;
    }

    dst[0] =  dst[0] ^ key[0];
    for (var i = 1; i <= 15; i++ ) {
        dst[i] = dst[i] ^ dst[i - 1] ^ key[i];
    }

    for (var i = 0; i <= 15; i++ ) {
        if (dst [i] == 0 ) {
            dst [i] = 0x66;
        }
    }

    var encrypted = "0x";
    for (var i = 0; i <= 15; i++ ) {
        if (dst [i] < 16 ) {
            encrypted = encrypted + "0";
        }
        encrypted = encrypted + dst[i].toString(16);

    }
    return (encrypted);
}

function ord(string) {
    //  discuss at: http://phpjs.org/functions/ord/
    // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // bugfixed by: Onno Marsman
    // improved by: Brett Zamir (http://brett-zamir.me)
    //    input by: incidence
    var str = string + '',
        code = str.charCodeAt(0);
    if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
        var hi = code;
        if (str.length === 1) {
            return code; // This is just a high surrogate with no following low surrogate, so we return its value;
            // we could also throw an error as it is not a complete character, but someone may want to know
        }
        var low = str.charCodeAt(1);
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
    }
    if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
        return code; // This is just a low surrogate with no preceding high surrogate, so we return its value;
        // we could also throw an error as it is not a complete character, but someone may want to know
    }
    return code;
}

function fmod(x, y) {
    //  discuss at: http://phpjs.org/functions/fmod/
    // original by: Onno Marsman
    //    input by: Brett Zamir (http://brett-zamir.me)
    // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    //   example 1: fmod(5.7, 1.3);
    //   returns 1: 0.5

    var tmp, tmp2, p = 0,
        pY = 0,
        l = 0.0,
        l2 = 0.0;

    tmp = x.toExponential()
        .match(/^.\.?(.*)e(.+)$/);
    p = parseInt(tmp[2], 10) - (tmp[1] + '')
        .length;
    tmp = y.toExponential()
        .match(/^.\.?(.*)e(.+)$/);
    pY = parseInt(tmp[2], 10) - (tmp[1] + '')
        .length;

    if (pY > p) {
        p = pY;
    }

    tmp2 = (x % y);

    if (p < -100 || p > 20) {
        // toFixed will give an out of bound error so we fix it like this:
        l = Math.round(Math.log(tmp2) / Math.log(10));
        l2 = Math.pow(10, l);

        return (tmp2 / l2)
            .toFixed(l - p) * l2;
    } else {
        return parseFloat(tmp2.toFixed(-p)); <<< ---- FAILS HERE ---------
    }
}

// PHP Original --------------------------------

function encrypt( $plain )
{
  $array_mul = array ( 0 => 213119, 1 => 213247, 2 => 213203, 3 => 213821 );
  $array_add = array ( 0 => 2529077, 1 => 2529089, 2 => 2529589, 3 => 2529997 );
  $dst = $key = array ( 0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0, 13 => 0, 14 => 0, 15 => 0 );

  for ( $i = 0; $i < strlen ( $plain ); $i++ ) {
    $dst [ $i ] = $key [ $i ] = ord ( substr ( $plain, $i, 1 ) );
  }

  for ( $i = 0; $i <= 3; $i++ ) {
    $val [ $i ] = fmod ( ( $key [ $i * 4 + 0 ] + $key [ $i * 4 + 1 ] * 0x100 + $key [ $i * 4 + 2 ] * 0x10000 + $key [ $i * 4 + 3 ] * 0x1000000 ) * $array_mul [ $i ] + $array_add [ $i ], 4294967296 );
  }

  for ( $i = 0; $i <= 3; $i++ ) {
    $key [ $i * 4 + 0 ] = $val [ $i ] & 0xff;
    $key [ $i * 4 + 1 ] = $val [ $i ] / 0x100 & 0xff;
    $key [ $i * 4 + 2 ] = $val [ $i ] / 0x10000 & 0xff;
    $key [ $i * 4 + 3 ] = $val [ $i ] / 0x1000000 & 0xff;
  }

  $dst [ 0 ] = $dst [ 0 ] ^ $key [ 0 ];
  for ( $i = 1; $i <= 15; $i++ ) {
    $dst [ $i ] = $dst [ $i ] ^ $dst [ $i - 1 ] ^ $key [ $i ];
  }

  for ( $i = 0; $i <= 15; $i++ ) {
    if ( $dst [ $i ] == 0 ) {
      $dst [ $i ] = 0x66;
    }
  }

  $encrypted = "0x";
  for ( $i = 0; $i <= 15; $i++ ) {
    if ( $dst [ $i ] < 16 ) {
      $encrypted .= "0";
    }
    $encrypted .= dechex($dst[$i]);
  }
  return ( $encrypted );
}
+4
source share
2 answers

-p parseFloat() 111, :

....
if (p < -100 || p > 20) {
    // toFixed will give an out of bound error so we fix it like this:
    l = Math.round(Math.log(tmp2) / Math.log(10));
    l2 = Math.pow(10, l);

    return (tmp2 / l2)
        .toFixed(l - p) * l2;
} else {
    return parseFloat(tmp2.toFixed(-p)); 
}

-p -1.

,

...
} else {

    for(var i=0; i<=20;i++) {
        console.log(parseFloat(tmp2.toFixed(i)));
    }
    //return parseFloat(tmp2.toFixed(-p)); 
}

2529997
2529997
2529997
...
2529997
2529997
2529997

, 101 .

tmp2 = (x % y);

JavaScript.

, , parseFloat() 112, :

...
} else {
    var i = Math.floor(Math.random()*20);
    return parseFloat(tmp2.toFixed(i)); 
}

script:

alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6
alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6
alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6
alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6
alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6
alain@vaio ~/dev/test % node script.js
0x31c7296631df873d0891b7b77ae0c6c6

, , p, .

.

, Number.prototype.toFixed() RangeError p > 0. - , p, :

> x = 12345; tmp = x.toExponential().match(/^.\.?(.*)e(.+)$/); p = parseInt(tmp[2], 10) - (tmp[1] + '').length;
0

> x = 1234567890123456789; tmp = x.toExponential().match(/^.\.?(.*)e(.+)$/); p = parseInt(tmp[2], 10) - (tmp[1] + '').length;
2

> x = 101000; tmp = x.toExponential().match(/^.\.?(.*)e(.+)$/); p = parseInt(tmp[2], 10) - (tmp[1] + '').length;
3

fmod x: 3626296650629732529077 y: 4294967296, p = 1.

fmod, :

if (p < -100 || p > 20) {
    // toFixed will give an out of bound error so we fix it like this:
    l = Math.round(Math.log(tmp2) / Math.log(10));
    l2 = Math.pow(10, l);

    return (tmp2 / l2)
        .toFixed(l - p) * l2;
} else if ( p > 0 ) {
    return parseFloat(tmp2.toFixed(p)); 
} else {
    return parseFloat(tmp2.toFixed(-p)); 
}

pCrypt2 x.

JavaScript . Number.prototype.toFixed().

+5

:

return parseFloat(tmp2.toFixed(-p));

:

return parseFloat(tmp2.toFixed(p));

http://jsfiddle.net/rd13/7UHdw/

0

Source: https://habr.com/ru/post/1533459/


All Articles