Skip to content

Instantly share code, notes, and snippets.

@Cacodaimon
Last active December 24, 2015 04:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cacodaimon/6743696 to your computer and use it in GitHub Desktop.
Save Cacodaimon/6743696 to your computer and use it in GitHub Desktop.
Easy to use Mcrypt wrapper class.
<?php
namespace Caco\Password;
/**
* Mcrypt wrapper class.
*
* @author Guido Krömer <mail@cacodaemon.de>
* @package Caco\Password
*/
class Mcrypt
{
/**
* @var array
*/
protected static $validCiphers = [
MCRYPT_BLOWFISH,
MCRYPT_TWOFISH,
MCRYPT_RIJNDAEL_128,
MCRYPT_RIJNDAEL_192,
MCRYPT_RIJNDAEL_256,
MCRYPT_SERPENT
];
/**
* @var string
*/
protected $cipher = MCRYPT_TWOFISH;
/**
* @var string
*/
protected $mode = MCRYPT_MODE_CBC;
/**
* @var string
*/
protected $keyHashRounds = '11';
/**
* Encrypts the data with the given key.
*
* @param string $data
* @param string $key
* @return McryptContainer
*/
public function encrypt($data, $key)
{
$data = trim($data);
$container = new McryptContainer;
$container->setInitializationVector($this->getInitializationVector());
$container->setPasswordSalt($this->generateSalt());
$container->setCipher($this->cipher);
$container->setData(mcrypt_encrypt(
$this->cipher,
$this->getKeyHash($key, $container->getPasswordSalt()),
sha1($data) . $data,
$this->mode,
$container->getInitializationVector()
));
return $container;
}
/**
* Decrypts the container data with the given key
* or returns false if the key is not valid.
*
* @param McryptContainer $container
* @param string $key
* @return bool|string
*/
public function decrypt(McryptContainer $container, $key)
{
$data = trim(mcrypt_decrypt(
$container->getCipher(),
$this->getKeyHash($key, $container->getPasswordSalt()),
$container->getData(),
$this->mode,
$container->getInitializationVector()
));
$checkSum = substr($data, 0, 40);
$data = substr($data, 40);
if (sha1($data) != $checkSum) {
return false;
}
return $data;
}
/**
* Generates a hash for the given key.
*
* @param string $key
* @return string
*/
protected function getKeyHash($key, $salt)
{
$length = mcrypt_enc_get_key_size(mcrypt_module_open($this->cipher, '', $this->mode, ''));
$hash = crypt($key, sprintf('$2a$%s$%s$', $this->keyHashRounds, $salt));
return substr($hash, $length * -1);
}
/**
* Generates a random salt.
*
* @return string
*/
protected function generateSalt()
{
$length = mcrypt_enc_get_key_size(mcrypt_module_open($this->cipher, '', $this->mode, ''));
$validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$salt = '';
$count = strlen($validChars) - 1;
while ($length--) {
$salt .= $validChars[mt_rand(0, $count)];
}
return $salt;
}
/**
* Generates a new mcrypt initialization vector.
*
* @return string
*/
protected function getInitializationVector()
{
return mcrypt_create_iv(mcrypt_get_iv_size($this->cipher, $this->mode), MCRYPT_DEV_URANDOM);
}
/**
* Sets the cipher.
*
* @param string $cipher
*/
public function setCipher($cipher)
{
if (!in_array($cipher, static::$validCiphers)) {
$msg = 'Given cipher is not supported, supported ciphers are: ' . implode(', ', static::$validCiphers);
throw new \InvalidArgumentException($msg);
}
$this->cipher = $cipher;
}
/**
* Sets the rounds used for hashing the key.
*
* @param string $keyHashRounds
*/
public function setKeyHashRounds($keyHashRounds)
{
$this->keyHashRounds = $keyHashRounds;
}
}
<?php
namespace Caco\Password;
/**
* Class McryptContainer
*
* @author Guido Krömer <mail@cacodaemon.de>
* @package Caco\Password
*/
class McryptContainer
{
/**
* @var string
*/
protected $data;
/**
* @var string
*/
protected $passwordSalt;
/**
* @var string
*/
protected $initializationVector;
/**
* @var string
*/
protected $cipher;
/**
* @param string $data
*/
public function setData($data)
{
$this->data = base64_encode($data);
}
/**
* @return string
*/
public function getData()
{
return base64_decode($this->data);
}
/**
* @param string $passwordSalt
*/
public function setPasswordSalt($passwordSalt)
{
$this->passwordSalt = base64_encode($passwordSalt);
}
/**
* @return string
*/
public function getPasswordSalt()
{
return base64_decode($this->passwordSalt);
}
/**
* @param string $initializationVector
*/
public function setInitializationVector($initializationVector)
{
$this->initializationVector = base64_encode($initializationVector);
}
/**
* @return string
*/
public function getInitializationVector()
{
return base64_decode($this->initializationVector);
}
/**
* @param string $cipher
*/
public function setCipher($cipher)
{
$this->cipher = $cipher;
}
/**
* @return string
*/
public function getCipher()
{
return $this->cipher;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment