Last active
May 7, 2016 00:24
-
-
Save aaronhurt/aa7caee4b756328ac4d6 to your computer and use it in GitHub Desktop.
This file contains 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 | |
/** | |
* Example with all methods and default keys: | |
* | |
* $crypt = new phpCrypt; | |
* | |
* $crypt->cipher = "blowfish"; | |
* printf("crypted == %s\ndecrypted == %s\n\n", ($crypted = $crypt->encrypt("hello world")), $crypt->decrypt($crypted)); | |
* | |
* $crypt->cipher = "xor"; | |
* printf("crypted == %s\ndecrypted == %s\n\n", ($crypted = $crypt->encrypt("hello world")), $crypt->decrypt($crypted)); | |
* | |
* $crypt->cipher = null; | |
* printf("crypted == %s\ndecrypted == %s\n\n", ($crypted = $crypt->encrypt("hello world")), $crypt->decrypt($crypted)); | |
* | |
* Outputs: | |
* | |
* crypted == E2wYAdbwbQBn%2B%2B2Fz0Z9ew%3D%3D | |
* decrypted == hello world | |
* | |
* crypted == BRwPHg5aDl5EDh0%3D | |
* decrypted == hello world | |
* | |
* crypted == aGVsbG8gd29ybGQ%3D | |
* decrypted == hello world | |
* | |
* Example compatible with command line ssl: | |
* | |
* $crypt = new phpCrypt(array('urlcode' => false)); | |
* | |
* var_dump($crypt->keys()); | |
* printf("crypted == %s\ndecrypted == %s", ($crypted = $crypt->encrypt("hello world")), $crypt->decrypt($crypted)); | |
* | |
* Outputs: | |
* | |
* object(stdClass)#2 (4) { | |
* ["binkey"]=> | |
* string(16) "mycrazy16bytekey" | |
* ["hexkey"]=> | |
* string(32) "6D796372617A793136627974656B6579" | |
* ["biniv"]=> | |
* string(8) "e2f4ebc6" | |
* ["hexiv"]=> | |
* string(16) "6532663465626336" | |
* } | |
* crypted == E2wYAdbwbQBn++2Fz0Z9ew== | |
* | |
* Example shell command: | |
* | |
* somehost:$ printf "hello world" | openssl enc -blowfish -K 6D796372617A793136627974656B6579 -iv 6532663465626336|base64 | |
* E2wYAdbwbQBn++2Fz0Z9ew== | |
*/ | |
/** | |
* PHP Encryption class with output compatability with openssl cli tools | |
*/ | |
class phpCrypt { | |
/** | |
* block size for padding/unpadding strings | |
* @var integer | |
*/ | |
public $blocksize = 8; | |
/** | |
* the cipher to use (aes, blowfish, xor or null) | |
* @var string | |
*/ | |
public $cipher = 'aes'; | |
/** | |
* the encryption key | |
* @var string | |
*/ | |
public $key = 'mycrazy16bytekey'; | |
/** | |
* optional hex iv | |
* @var string | |
*/ | |
public $hexiv = null; | |
/** | |
* optional hex key | |
* @var string | |
*/ | |
public $hexkey = null; | |
/** | |
* urlencode/urldecode all output/input strings | |
* @var boolean | |
*/ | |
public $urlcode = true; | |
/** | |
* base64encode/base64decode all output/input strings | |
* @var boolean | |
*/ | |
public $base64code = true; | |
/** | |
* phpCrypt class constructor | |
* @param array $phpCryptParams array of initialization properties | |
*/ | |
public function __construct(array $phpCryptParams = array()) { | |
foreach ($phpCryptParams as $key => $val) { | |
if (property_exists($this, $key)) { | |
$this->$key = $val; | |
} | |
} | |
} | |
/** | |
* XOR strings with keys for pseudo encryption | |
* @param string $string plain text input string | |
* @param string $key key value (optional) | |
* @return string thd xor'd string | |
*/ | |
public function sxor($string, $key = null) { | |
/* check key */ | |
if ($key === null) $key = $this->key; | |
/* init arrays */ | |
$output = array(); | |
$input = str_split($string); | |
$key = str_split($key); | |
/* get lengths */ | |
$input_count = count($input); | |
$key_count = count($key); | |
/* xor string with key */ | |
for ($i = 0, $k = 0; $i < $input_count; $i++) { | |
$output[$i] = $input[$i] ^ $key[$k]; | |
/* get next key - loop if needed */ | |
$k = (($k + 1) >= $key_count) ? 0 : ($k + 1); | |
} | |
/* return joined output */ | |
return join('', $output); | |
} | |
/** | |
* Add PKCS5 block padding to string | |
* @param string $string the string to pad | |
* @param integer $blocksize block size/length in bytes (optional) | |
* @return string the padded string | |
*/ | |
public function pad($string, $blocksize = null) { | |
/* check blocksize */ | |
if ($blocksize === null) $blocksize = $this->blocksize; | |
/* original string length */ | |
$slength = strlen($string); | |
/* the padding */ | |
$padding = ($blocksize - ($slength % $blocksize)); | |
/* return padded string */ | |
return str_pad($string, ($slength + $padding), chr($padding)); | |
} | |
/** | |
* Removes PKCS5 block padding from string | |
* @param string $string the padded string | |
* @return string the unpadded string | |
* @throws Exception on corrupt strings | |
*/ | |
public function unpad($string) { | |
/* padded string length */ | |
$slength = strlen($string); | |
/* the padding */ | |
$padding = ord(substr($string, -1)); | |
/* check lengths */ | |
if ($padding > $slength) { | |
/* bad lengths */ | |
throw new Exception('corrupt pkcs5 string - padding length greater than string length'); | |
} | |
/* check padding */ | |
if (strspn($string, chr($padding), ($slength - $padding)) !== $padding) { | |
/* padding doesn't match */ | |
throw new Exception('corrupt pkcs5 string - padding does not match'); | |
} | |
/* looks good ... return string minus padding */ | |
return substr($string, 0, ($slength - $padding)); | |
} | |
/** | |
* Generate compliant encryption keys and init vectors for CBC methods | |
* @param string $key the encryption key (optional) | |
* @param integer $keysize final byte length of the encryption key (optional) | |
* @param integer $ivsize final byte length of the init vector (optional) | |
* @return object object containing strings: binkey, hexkey, biniv, hexiv | |
*/ | |
public function keys($key = null, $keysize, $ivsize) { | |
/* check key */ | |
if ($key === null) $key = $this->key; | |
/* init return object */ | |
$retval = new stdClass(); | |
/* generate the bin key */ | |
if ($this->hexkey !== null) { | |
/* set hex key as is */ | |
$retval->hexkey = $this->hexkey; | |
/* decode passed hex for bin */ | |
$retval->binkey = hex2bin($this->hexkey); | |
} else { | |
/* generate key */ | |
$retval->binkey = substr(str_pad($key, $keysize, "\0"), 0, $keysize); | |
/* encode hex key */ | |
$retval->hexkey = strtoupper(bin2hex($retval->binkey)); | |
} | |
/* check for hex iv */ | |
if ($this->hexiv !== null) { | |
/* set hex iv as is */ | |
$retval->hexiv = $this->hexiv; | |
/* decode hex for bin */ | |
$retval->biniv = hex2bin($this->hexiv); | |
} else { | |
/* check passed key */ | |
if (strlen($key)) { | |
/* generate bin vector from key hash */ | |
$retval->biniv = substr(md5($key), 0, $ivsize); | |
} else { | |
/* make null vector */ | |
$retval->biniv = str_pad("", $ivsize, "\0"); | |
} | |
/* encode hex vector */ | |
$retval->hexiv = strtoupper(bin2hex($retval->biniv)); | |
} | |
/* return the object */ | |
return $retval; | |
} | |
/** | |
* Encrypt and encode strings for general use | |
* @param string $plain plain text string to be encrypted | |
* @throws Exception on missing builtin functions | |
* @return string the encrypted/encoded string | |
*/ | |
public function encrypt($plain) { | |
/* switch based on type */ | |
switch(strtolower($this->cipher)) { | |
case "xor": | |
/* xor plain with key */ | |
$output = $this->sxor($plain); | |
break; | |
case "aes" : | |
/* check for function and constant */ | |
if (!function_exists('mcrypt_decrypt') || !constant("MCRYPT_RIJNDAEL_128")) { | |
/* throw exception - nothing else we can do */ | |
throw new Exception('missing mcrypt function or constant'); | |
} | |
/* generate key and init vector */ | |
$cbc = $this->keys($this->key, 16, 16); | |
/* encrypt the string with pkcs5 padding */ | |
$output = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $cbc->binkey, $this->pad($plain), | |
MCRYPT_MODE_CBC, $cbc->biniv); | |
break; | |
case "blowfish" : | |
/* check for function and constant */ | |
if (!function_exists('mcrypt_decrypt') || !constant("MCRYPT_BLOWFISH")) { | |
/* throw exception - nothing else we can do */ | |
throw new Exception('missing mcrypt function or constant'); | |
} | |
/* generate key and init vector */ | |
$cbc = $this->keys($this->key, 16, 8); | |
/* encrypt the string with pkcs5 padding */ | |
$output = mcrypt_encrypt(MCRYPT_BLOWFISH, $cbc->binkey, $this->pad($plain), | |
MCRYPT_MODE_CBC, $cbc->biniv); | |
break; | |
default: | |
/* use plain as output */ | |
$output = $plain; | |
break; | |
} | |
/* base64 encode */ | |
if ($this->base64code === true) { | |
$output = base64_encode($output); | |
} | |
/* url encode */ | |
if ($this->urlcode === true) { | |
$output = urlencode($output); | |
} | |
/* return */ | |
return $output; | |
} | |
/** | |
* Decode and decrypt strings for general use | |
* @param string $crypted string to be decrypted | |
* @throws Exception on missing builtin functions | |
* @return string the decoded/decrypted string | |
*/ | |
public function decrypt($crypted) { | |
/* url decode */ | |
if ($this->urlcode === true) { | |
$crypted = urldecode($crypted); | |
} | |
/* base64 decode */ | |
if ($this->base64code === true) { | |
$crypted = base64_decode($crypted); | |
} | |
/* switch based on type */ | |
switch(strtolower($this->cipher)) { | |
case "xor" : | |
/* xor crypted with key */ | |
$plain = $this->sxor($crypted); | |
break; | |
case "aes" : | |
/* check for function and constant */ | |
if (!function_exists('mcrypt_decrypt') || !constant("MCRYPT_RIJNDAEL_128")) { | |
/* throw exception - nothing else we can do */ | |
throw new Exception('missing mcrypt function or constant'); | |
} | |
/* generate key and init vector */ | |
$cbc = $this->keys($this->key, 16, 16); | |
/* encrypt the string with pkcs5 padding */ | |
$plain = $this->unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $cbc->binkey, $crypted, | |
MCRYPT_MODE_CBC, $cbc->biniv)); | |
break; | |
case "blowfish" : | |
/* check for function and constant */ | |
if (!function_exists('mcrypt_decrypt') || !constant("MCRYPT_BLOWFISH")) { | |
/* throw exception - nothing else we can do */ | |
throw new Exception('missing mcrypt function or constant'); | |
} | |
/* generate key and init vector */ | |
$cbc = $this->keys($this->key, 16, 8); | |
/* encrypt the string with pkcs5 padding */ | |
$plain = $this->unpad(mcrypt_decrypt(MCRYPT_BLOWFISH, $cbc->binkey, $crypted, | |
MCRYPT_MODE_CBC, $cbc->biniv)); | |
break; | |
default: | |
/* use plain as output */ | |
$plain = $crypted; | |
break; | |
} | |
/* return */ | |
return $plain; | |
} | |
} |
This file contains 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
#!/usr/bin/env php | |
<?php | |
/* only run from the cli */ | |
if (php_sapi_name() !== 'cli') { | |
die('This script may only be run from the command line.' . "\n"); | |
} | |
/* check arguments */ | |
if ($argc < 5) { | |
die('Usage: ' . $argv[0] . ' <encrypt|decrypt> <hex key> <hex iv> <string>' . "\n"); | |
} | |
/* pull in functions */ | |
require_once(realpath(dirname(__FILE__)) . '/php-crypt.php'); | |
/* build and setup object */ | |
$crypt = new phpCrypt; | |
$crypt->cipher = "aes"; | |
$crypt->key = null; | |
$crypt->hexkey = $argv[2]; | |
$crypt->hexiv = $argv[3]; | |
$crypt->urlcode = false; | |
/* prep text */ | |
$text = str_replace(array('-', '_'), array('+', '/'), $argv[4]); | |
/* switch based on command */ | |
switch(strtolower($argv[1])) { | |
case 'encrypt': | |
printf("%s\n", $crypt->encrypt($text)); | |
break; | |
case 'decrypt': | |
printf("%s\n", $crypt->decrypt($text)); | |
break; | |
} | |
/* exit clean */ | |
exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment