Description: 128 bit Password encrytion system utilizing three concurrent md5 password hashes, where the 3rd and final hash is utilized as the key for an implementation of the blowfish algorithm.
require_once 'PEAR.php';
class Crypt_Blowfish
{
var $_P = array();
var $_S = array();
var $_td = null;
var $_iv = null;
function Crypt_Blowfish($key)
{
if (extension_loaded('mcrypt')) {
$this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
$this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
}
$this->setKey($key);
}
function isReady()
{
return true;
}
function init()
{
$this->_init();
}
function _init()
{
$defaults = new Crypt_Blowfish_DefaultKey();
$this->_P = $defaults->P;
$this->_S = $defaults->S;
}
function _encipher(&$Xl, &$Xr)
{
for ($i = 0; $i < 16; $i++) {
$temp = $Xl ^ $this->_P[$i];
$Xl = ((($this->_S[0][($temp>>24) & 255] +
$this->_S[1][($temp>>16) & 255]) ^
$this->_S[2][($temp>>8) & 255]) +
$this->_S[3][$temp & 255]) ^ $Xr;
$Xr = $temp;
}
$Xr = $Xl ^ $this->_P[16];
$Xl = $temp ^ $this->_P[17];
}
function _decipher(&$Xl, &$Xr)
{
for ($i = 17; $i > 1; $i--) {
$temp = $Xl ^ $this->_P[$i];
$Xl = ((($this->_S[0][($temp>>24) & 255] +
$this->_S[1][($temp>>16) & 255]) ^
$this->_S[2][($temp>>8) & 255]) +
$this->_S[3][$temp & 255]) ^ $Xr;
$Xr = $temp;
}
$Xr = $Xl ^ $this->_P[1];
$Xl = $temp ^ $this->_P[0];
}
function encrypt($plainText)
{
if (!is_string($plainText)) {
PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
}
if (extension_loaded('mcrypt')) {
return mcrypt_generic($this->_td, $plainText);
}
$cipherText = '';
$len = strlen($plainText);
$plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
for ($i = 0; $i < $len; $i += 8) {
list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
$this->_encipher($Xl, $Xr);
$cipherText .= pack("N2", $Xl, $Xr);
}
return $cipherText;
}
function decrypt($cipherText)
{
if (!is_string($cipherText)) {
PEAR::raiseError('Chiper text must be a string', 1, PEAR_ERROR_DIE);
}
if (extension_loaded('mcrypt')) {
return mdecrypt_generic($this->_td, $cipherText);
}
$plainText = '';
$len = strlen($cipherText);
$cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
for ($i = 0; $i < $len; $i += 8) {
list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
$this->_decipher($Xl, $Xr);
$plainText .= pack("N2", $Xl, $Xr);
}
return $plainText;
}
function setKey($key)
{
if (!is_string($key)) {
PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
}
$len = strlen($key);
if ($len > 56 || $len == 0) {
PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
}
if (extension_loaded('mcrypt')) {
mcrypt_generic_init($this->_td, $key, $this->_iv);
return true;
}
require_once 'Blowfish/DefaultKey.php';
$this->_init();
$k = 0;
$data = 0;
$datal = 0;
$datar = 0;
for ($i = 0; $i < 18; $i++) {
$data = 0;
for ($j = 4; $j > 0; $j--) {
$data = $data << 8 | ord($key{$k});
$k = ($k+1) % $len;
}
$this->_P[$i] ^= $data;
}
for ($i = 0; $i <= 16; $i += 2) {
$this->_encipher($datal, $datar);
$this->_P[$i] = $datal;
$this->_P[$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[0][$i] = $datal;
$this->_S[0][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[1][$i] = $datal;
$this->_S[1][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[2][$i] = $datal;
$this->_S[2][$i+1] = $datar;
}
for ($i = 0; $i < 256; $i += 2) {
$this->_encipher($datal, $datar);
$this->_S[3][$i] = $datal;
$this->_S[3][$i+1] = $datar;
}
return true;
}
}
function Eencrypt($cipher, $plaintext){
$ciphertext = "";
$paddedtext = maxi_pad($plaintext);
$strlen = strlen($paddedtext);
for($x=0; $x< $strlen; $x+=8){
$piece = substr($paddedtext,$x,8);
$cipher_piece = $cipher->encrypt($piece);
$encoded = base64_encode($cipher_piece);
$ciphertext = $ciphertext.$encoded;
}
return $ciphertext;
}
function Edecrypt($cipher,$ciphertext){
$plaintext = "";
$chunks = split("=",$ciphertext);
$ending_value = count($chunks) ;
for($counter=0 ; $counter < ($ending_value-1) ; $counter++)
{
$chunk = $chunks[$counter]."=";
$decoded = base64_decode($chunk);
$piece = $cipher->decrypt($decoded);
$plaintext = $plaintext.$piece;
}
return $plaintext;
}
function maxi_pad($plaintext){
$str_len = count($plaintext);
//plain text must be div by 8
$pad_len = $str_len % 8;
for($x=0; $x<$pad_len; $x++){
$plaintext = $plaintext." ";
}
$str_len = count($plaintext);
if($srt_len % 8){
print "padding function is not working\n";
}else{
return $plaintext;
}
return (-1);
}
function createRandomPassword() {
$chars = "abcdefghijkmnopqrstuvwxyz023456789,./<>?`~!@#$%^&*()_+-={}|[]\:;";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i <= 10) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
// Usage
$user ="admin";
$password = createRandomPassword();
// print random password
echo "Your random password is: $password <BR>";
$salt = substr(md5(uniqid(rand(), true)), 0, 5);
$hash1 = md5($user->salt . md5($password)); // hash password once
$hash2 = md5($user->salt . md5($hash1)); // hash password twice
$hash3 = md5($hash1->salt . md5($hash2)); // hash password three times</b>
$final_hash = $hash3;
// print triple hashed password with combined hash from second algorythum
echo "Final hashed password is: $final_hash<p>";
//NOTE: This is the key or password for encrypting your files.
// THIS MUST BE 8 CHARACTERS
$key = $hash3;
//This is the text to be encrypted
$plaintext = $final_hash;
//This is a blowfish cipher object
$cipher = new Crypt_Blowfish($key);
//This is the encrypted text
$ciphertext = Eencrypt($cipher,$plaintext);
// TRIPLE HASH WITH BLOWFISH ENCRYPTION
echo "Final hashed password with blowfish encryption is: $ciphertext";