Advertisement
Guest User

php-crypt-md5.js

a guest
Jun 8th, 2013
2,790
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function () {
  2.     // Shortcuts
  3.     var C = CryptoJS;
  4.     var C_lib = C.lib;
  5.     var Base = C_lib.Base;
  6.     var WordArray = C_lib.WordArray;
  7.     var C_algo = C.algo;
  8.     var MD5 = C_algo.MD5;
  9.     var Utf8 = C.enc.Utf8;
  10.  
  11.     // Constants
  12.     var SALT_MAXLEN = 8;
  13.     var MD5_MAGIC = "$1$";
  14.  
  15.     var PHP_CRYPT_MD5 = C_algo.PHP_CRYPT_MD5 = Base.extend({
  16.  
  17.         /**
  18.          * Initializes a newly created Password hashing function.
  19.          *
  20.          * @example
  21.          *
  22.          *     var md5crypt = CryptoJS.algo.PHP_CRYPT_MD5.create();
  23.          */
  24.         init: function () {
  25.         },
  26.  
  27.         /**
  28.          * Computes the the PHP MD5 based crypt hash
  29.          *
  30.          * @param {WordArray|string} password The password.
  31.          * @param {string} salt A salt (this can be the output of the crypt
  32.          *      function).
  33.          *
  34.          * @return {string} The password hash
  35.          *
  36.          * @example
  37.          *
  38.          *     var hash = kdf.compute(password, salt);
  39.          */
  40.         compute: function (password, salt) {
  41.             if (typeof password == 'string') {
  42.                 password = Utf8.parse(password);
  43.             }
  44.  
  45.             var saltStart = 0;
  46.             if(salt.indexOf(MD5_MAGIC) === 0) {
  47.                 saltStart += MD5_MAGIC.length;
  48.             }
  49.  
  50.             var saltEnd = Math.min(SALT_MAXLEN+MD5_MAGIC.length,
  51.                 salt.indexOf("$", saltStart));
  52.  
  53.             if(saltEnd < 0) {
  54.                 saltEnd = SALT_MAXLEN + MD5_MAGIC.length;
  55.             }
  56.             var realSalt = salt.substring(saltStart, saltEnd);
  57.  
  58.             var ctx = MD5.create();
  59.  
  60.             ctx.update(password);
  61.             ctx.update(realSalt);
  62.             ctx.update(password);
  63.  
  64.             var fin = ctx.finalize();
  65.  
  66.             ctx.reset();
  67.  
  68.             ctx.update(password);
  69.             ctx.update(MD5_MAGIC);
  70.             ctx.update(realSalt);
  71.  
  72.             for(var pl = password.sigBytes; pl > 0; pl -= 16) {
  73.                 var words = WordArray.create(
  74.                         fin.words, Math.min(pl, 16)
  75.                 );
  76.                 ctx.update(words);
  77.             }
  78.  
  79.             var empty = WordArray.create([0], 1);
  80.             var pwc1 = WordArray.create(password.words, 1);
  81.             for(var i = password.sigBytes; i !== 0; i >>>= 1) {
  82.                 if((i & 1) !== 0) {
  83.                     ctx.update(empty);
  84.                 } else {
  85.                     ctx.update(pwc1);
  86.                 }
  87.             }
  88.  
  89.             fin = ctx.finalize();
  90.  
  91.             for(i = 0; i < 1000; ++i) {
  92.                 ctx.reset();
  93.  
  94.                 if((i & 1) !== 0) {
  95.                     ctx.update(password);
  96.                 } else {
  97.                     ctx.update(fin);
  98.                 }
  99.  
  100.                 if((i % 3) !== 0) {
  101.                     ctx.update(realSalt);
  102.                 }
  103.  
  104.                 if((i % 7) !== 0) {
  105.                     ctx.update(password);
  106.                 }
  107.  
  108.                 if((i & 1) !== 0) {
  109.                     ctx.update(fin);
  110.                 } else {
  111.                     ctx.update(password);
  112.                 }
  113.  
  114.                 fin = ctx.finalize();
  115.             }
  116.  
  117.             var finb = this.wordArrayToByteArray(fin);
  118.             var result = MD5_MAGIC + realSalt + "$" +
  119.                 this.to64((finb[ 0] << 16) | (finb[ 6] << 8) | finb[12], 4) +
  120.                 this.to64((finb[ 1] << 16) | (finb[ 7] << 8) | finb[13], 4) +
  121.                 this.to64((finb[ 2] << 16) | (finb[ 8] << 8) | finb[14], 4) +
  122.                 this.to64((finb[ 3] << 16) | (finb[ 9] << 8) | finb[15], 4) +
  123.                 this.to64((finb[ 4] << 16) | (finb[10] << 8) | finb[ 5], 4) +
  124.                 this.to64( finb[11], 2);
  125.  
  126.             return result;
  127.         },
  128.  
  129.         /**
  130.          * Converts a WordArray-object to an array of bytes. I'm surprised that
  131.          * this is not part of the CryptoJS library.
  132.          *
  133.          * @param {WordArray} wa The numeric value to be converted
  134.          *
  135.          * @return {array} The bytes contained in the WordArray object
  136.          */
  137.         wordArrayToByteArray: function(wa) {
  138.             var bytes = [], words = wa.words;
  139.  
  140.             for(var i = 0; i < wa.sigBytes; ++i) {
  141.                 var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  142.  
  143.                 bytes.push(bite);
  144.             }
  145.  
  146.             return bytes;
  147.         },
  148.  
  149.         /**
  150.          * Implements the to64-function used by the php_md5_crypt_r function.
  151.          *
  152.          * @param {number} v The numeric value to be converted
  153.          * @param {number} n The number of digits to return
  154.          *
  155.          * @return {string} The base64 digits.
  156.          */
  157.         to64: function(v, n) {
  158.             var itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
  159.                 "abcdefghijklmnopqrstuvwxyz";
  160.             var result = "";
  161.  
  162.             while(--n >= 0) {
  163.                 result += itoa64.charAt(v & 0x3f);
  164.                 v >>= 6;
  165.             }
  166.  
  167.             return result;
  168.         }
  169.     });
  170.  
  171.     /**
  172.      * Computes the the PHP MD5 based crypt hash
  173.      *
  174.      * @param {WordArray|string} password The password.
  175.      * @param {string} salt A salt.
  176.      *
  177.      * @return {string} The password hash
  178.      *
  179.      * @static
  180.      *
  181.      * @example
  182.      *
  183.      *     var hash = CryptoJS.PHP_CRYPT_MD5(password, salt);
  184.      */
  185.     C.PHP_CRYPT_MD5 = function (password, salt) {
  186.         return PHP_CRYPT_MD5.create().compute(password, salt);
  187.     };
  188. }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement