Subversion Repositories sysadmin_scripts

Rev

Rev 26 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

/*
 * Check password for inclusion in lists maintained by 
 * https://haveibeenpwned.com/ using their API.
 * 
 * Copyright (C) [2019] by Daily Data, Inc <https://dailydata.net>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions 
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Attribution to Troy Hunt at https://haveibeenpwned.com/ must appear
 *    on any page which uses this set of scripts.
 * 3. Attribution to Daily Data, Inc. (https://dailydata.net) is optional
 *    but appreciated.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 * 
 */

var pre_hash = null;
var post_hash = null;

$( document ).ready(function() {  //Once the document is ready
    $("button#lookup").click( // When the button is clicked
            function(event) {
                //Set the result div so if the request takes a while, the user will know it's working.
                $("div#result").html("Checking password against password list, please wait...");
                //And now process the query.
                processQuery($("input#password").val());
                
            });
});

async function processQuery( str ) {
  //Crypto stuff to use modern browsers SHA functions to create the hash.
  const buffer = new TextEncoder( 'utf-8' ).encode( str );
  const digest = await crypto.subtle.digest('SHA-1', buffer);

  // Convert digest to hex string
  const result = Array.from(new Uint8Array(digest)).map( x => x.toString(16).padStart(2,'0') ).join('');
  
  //Once this is done, take the result and make the AJAX call.
  pre_hash = result.substring(0,5).toUpperCase();
  post_hash = result.substring(5,result.length).toUpperCase();
  
  console.log("Full hash: " + result);
  console.log("Pre_hash: " + pre_hash);
  console.log("Post_hash: " + post_hash);
  console.log("Making AJAX call for " + pre_hash + ".");
  
  var url = "https://api.pwnedpasswords.com/range/" + pre_hash;
  $.get( url, function( data ) {
        var lines = data.split('\n');
        var found = false;
        console.log("Returned lines:");
        console.log(lines.length);
        
        //If we got here, it was successful, so check the returned lines for a match.
        for(let line of lines) {
            var tmp_line = line.split(":");
            console.log("Testing " + post_hash + " vs " + tmp_line[0]);
            if(post_hash === tmp_line[0]) {
                //Got a match!
                console.log("*** MATCH FOUND *** ");
                $("div#result").html("<b>Warning: That password was found " + tmp_line[1] + " times!</b><br />We recommend you never use this password.");
                found = true;
                break;
            }
          };
          
        if(found === false) { 
            $("div#result").html("Password was not found in any lists.<br />However, this does not guarantee it is a good password.");
        }
    });
}