Created
August 4, 2017 03:36
-
-
Save ssigwart/cf5bdd1028c96d021ad06b7768075f38 to your computer and use it in GitHub Desktop.
Lookup a password to see if it's been cracked in a breach.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
# Download text file from https://haveibeenpwned.com/Passwords | |
/** Password SHA1 searches */ | |
class PasswordSha1Search | |
{ | |
/** Line Size (sha1 + \r\n) */ | |
const RECORD_SIZE = 42; | |
/** File */ | |
private $file = null; | |
/** Number of lines */ | |
private $numLines = 0; | |
/** Constructor */ | |
public function __construct() | |
{ | |
$this->file = fopen('pwned-passwords-1.0.txt', 'r'); | |
if ($this->file === false) | |
{ | |
print "Failed to open file.\n"; | |
exit(1); | |
} | |
// Compute number of lines | |
fseek($this->file, 0, SEEK_END); | |
$this->numLines = ftell($this->file)/self::RECORD_SIZE; | |
} | |
/** | |
* Look up a SHA1 | |
* | |
* @param string $sha1 SHA1 of password | |
* | |
* @return bool True if found | |
*/ | |
public function lookupSha1($sha1) | |
{ | |
return $this->_lookupSha1(strtoupper($sha1), 0, $this->numLines); | |
} | |
/** | |
* Look up a SHA1 and output whether it's found or not | |
* | |
* @param string $sha1 SHA1 of password | |
*/ | |
public function lookupSha1Output($sha1) | |
{ | |
if ($this->lookupSha1($sha1)) | |
print "Password found!\n"; | |
else | |
print "Password NOT found!\n"; | |
} | |
/** | |
* Binary search for a SHA1 | |
* | |
* @param string $sha1 SHA1 of password (uppercase) | |
* | |
* @return bool True if found | |
*/ | |
private function _lookupSha1($sha1, $min, $max) | |
{ | |
// Done? | |
if ($min > $max) | |
return false; | |
// Check midpoint | |
$mid = $min+(int)(($max-$min)/2); | |
fseek($this->file, self::RECORD_SIZE*$mid, SEEK_SET); | |
$recordSha1 = fread($this->file, 40); | |
// Match | |
$cmp = strcmp($sha1, $recordSha1); | |
if ($cmp === 0) | |
return true; | |
else if ($cmp < 0) | |
return $this->_lookupSha1($sha1, $min, $mid-1); | |
else | |
return $this->_lookupSha1($sha1, $mid+1, $max); | |
} | |
} | |
// Load class | |
$search = new PasswordSha1Search(); | |
// SHA1 on command line | |
$sha1 = isset($argv[1]) ? $argv[1] : null; | |
if ($sha1 !== null && strlen($sha1) === 40) | |
$search->lookupSha1Output($sha1); | |
else | |
{ | |
// Allow user to type passwords | |
print "Enter passwords to look up. When you are done, enter a blank link.\n"; | |
$continue = true; | |
do | |
{ | |
// Get password | |
echo 'Password: '; | |
system('stty -echo'); | |
$password = trim(fgets(STDIN)); | |
system('stty echo'); | |
print PHP_EOL; | |
// Is there a password? | |
$continue = ($password !== ''); | |
if ($continue) | |
{ | |
// Construct and print SHA1 | |
$sha1 = sha1($password); | |
print $sha1 . PHP_EOL; | |
// Check if it's found | |
$search->lookupSha1Output($sha1); | |
// Separator | |
print PHP_EOL . '--------------------------------------------------------------------------------' . PHP_EOL . PHP_EOL; | |
} | |
} while ($continue); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment