Skip to content

Instantly share code, notes, and snippets.

@eightyknots
Last active August 29, 2015 14:23
Show Gist options
  • Save eightyknots/69048f445ff890b14c6a to your computer and use it in GitHub Desktop.
Save eightyknots/69048f445ff890b14c6a to your computer and use it in GitHub Desktop.
[19JUN15] Encryption exercise
<?php
namespace Enigma;
class Encrypt {
protected $_cyphertext;
protected $_salt;
protected $_iv;
protected $_vernamtext;
protected $_outputtext;
public function __construct($plaintext, $password)
{
// Generate key and IV
$key = openssl_random_pseudo_bytes(32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$this->_iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
// Encrypt immediately
$this->_cyphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, trim($plaintext), MCRYPT_MODE_CBC, $this->_iv);
// Generate passphrase
$this->_salt = openssl_random_pseudo_bytes(32);
$passphrase = hash('sha256', $password.$this->_salt);
$verify = hash('sha512', $plaintext.$this->_cyphertext.$this->_salt);
// Generate Vernamtext
$this->_vernamtext = $key ^ $passphrase;
$this->_outputtext = implode(':', array(
base64_encode($this->_salt),
base64_encode($this->_iv),
base64_encode($verify),
base64_encode($this->_vernamtext),
base64_encode($this->_cyphertext)
));
}
public function get()
{
return (is_null($this->_outputtext) ? false : $this->_outputtext);
}
}
class Decrypt {
protected $_plaintext;
protected $_cyphertext;
protected $_vernamtext;
protected $_salt;
protected $_iv;
public function __construct(Encrypt $input, $password)
{
if (!$input->get()) {
return;
} else {
$inputtext = $input->get();
}
// Split input into the right parts, get the right key
list($salt, $iv, $verify, $vernamtext, $cyphertext) = explode(':', $inputtext);
$this->_salt = base64_decode($salt);
$this->_iv = base64_decode($iv);
$verify = base64_decode($verify);
$this->_vernamtext = base64_decode($vernamtext);
$this->_cyphertext = base64_decode($cyphertext);
$passphrase = hash('sha256', $password.$this->_salt);
$key = $this->_vernamtext ^ $passphrase;
// Decrypt the input
$this->_plaintext = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $this->_cyphertext, MCRYPT_MODE_CBC, $this->_iv));
// Generate verification
if (hash('sha512', $this->_plaintext.$this->_cyphertext.$this->_salt) !== $verify) {
$this->_plaintext = null;
throw new \Exception('Decryption failed: could not verify data integrity. Password is probably wrong');
}
}
public function get()
{
return (is_null($this->_plaintext) ? false : $this->_plaintext);
}
}
<?php
require_once('./enigma.php');
$text = 'Here lies a test string. May it rest in peace!';
$password = 'MyP00rlyCreatedPassword!';
$hash = sha1(trim($text));
$encrypted = new Enigma\Encrypt($text, $password);
$decrypted = new Enigma\Decrypt($encrypted, $password);
$final = sha1(trim($decrypted->get()));
if ($final === $hash) {
echo "\nOK.\n";
} else {
echo "\nNOT OK.\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment