Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Mcrypt Encryption Functions : mcrypt_encrypt

mcrypt_encrypt

Encrypts plaintext with given parameters (PHP 4 >= 4.0.2, PHP 5)
string mcrypt_encrypt ( string cipher, string key, string data, string mode [, string iv] )

Example 1294. mcrypt_encrypt() Example

<?php
   $iv_size
= mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
   
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
   
$key = "This is a very secret key";
   
$text = "Meet me at 11 o'clock behind the monument.";
   echo
strlen($text) . "\n";

   
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
   echo
strlen($crypttext) . "\n";
?>

The above example will output:

42
64

Code Examples / Notes » mcrypt_encrypt

chris

[Editor's note: original script posted by
andrewcare at execulink dot com
07-Jul-2004 04:45]
I needed to add
trim($data)
to andrew's example for it to remove some leftover hex garbage from the decrypted string.
Here's the working example:
<?php
$data = "Plaintext"; // Data to encrypt (http://www.ciphersbyritter.com/glossary.htm#Encryption)
$key = "Secret"; // Encryption key (http://www.ciphersbyritter.com/glossary.htm#Key)
$td = MCRYPT_RIJNDAEL_256; // Encryption cipher (http://www.ciphersbyritter.com/glossary.htm#Cipher)
$iv_size = mcrypt_get_iv_size($td, MCRYPT_MODE_ECB); // Dependant on cipher/mode combination (http://www.php.net/manual/en/function.mcrypt-get-iv-size.php)
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); // Creates an IV (http://www.ciphersbyritter.com/glossary.htm#IV)
echo "Original data: $data<br />";
$encrypted_data = mcrypt_encrypt($td, $key, $data, MCRYPT_MODE_CBC, $iv); // Encrypts data (http://www.php.net/manual/en/function.mcrypt-encrypt.php)
echo "Encrypted data: " . bin2hex($encrypted_data)  . "<br />"; // bin2hex to compensate for random character values
$data = mcrypt_decrypt($td, $key, $encrypted_data, MCRYPT_MODE_CBC, $iv); // Decrypts data (http://www.php.net/manual/en/function.mcrypt-decrypt.php)
echo trim($data);
?>
Thanks andrew, you saved me some time! Hope this saves someone else!


jesse

Solving 3DES incompatibilities with .NET's TripleDESCryptoServiceProvider
mcrypt's 3DES only accepts 192 bit keys, but Microsoft's .NET and many other tools accept both 128 and 192 bit keys.
If your key is too short, mcrypt will 'helpfully' pad null characters onto the end, but .NET refuses to use a key where the last third is all null (this is a Bad Key). This prevents you from emulating mcrypt's "short key" behaviour in .NET.
How to reconcile this? A little DES theory is in order
3DES runs the DES algorithm three times, using each third of your 192 bit key as the 64 bit DES key
Encrypt Key1 -> Decrypt Key2 -> Encrypt Key3
and both .NET and PHP's mcrypt do this the same way.
The problem arises in short key mode on .NET, since 128 bits is only two 64 bit DES keys
The algorithm that they use then is:
Encrypt Key1 -> Decrypt Key2 -> Encrypt Key1
mcrypt does not have this mode of operation natively.
but before you go and start running DES three times yourself, here's a Quick Fix
<?php
$my_key = "12345678abcdefgh"; // a 128 bit (16 byte) key
$my_key .= substr($my_key,0,8); // append the first 8 bytes onto the end
$secret = mcrypt_encrypt(MCRYPT_3DES, $my_key, $data, MCRYPT_MODE_CBC, $iv);  //CBC is the default mode in .NET
?>
And, like magic, it works.
There's one more caveat: Data padding
mcrypt always pads data will the null character
but .NET has two padding modes: "Zeros" and "PKCS7"
Zeros is identical to the mcrypt scheme, but PKCS7 is the default.
PKCS7 isn't much more complex, though:
instead of nulls, it appends the total number of padding bytes (which means, for 3DES, it can be a value from 0x01 to 0x07)
if your plaintext is "ABC", it will be padded into:
0x41 0x42 0x43 0x05 0x05 0x05 0x05 0x05
You can remove these from a decrypted string in PHP by counting the number of times that last character appears, and if it matches it's ordinal value, truncating the string by that many characters:
<?php
   $block = mcrypt_get_block_size('tripledes', 'cbc');
   $packing = ord($text{strlen($text) - 1});
   if($packing and ($packing < $block)){
     for($P = strlen($text) - 1; $P >= strlen($text) - $packing; $P--){
if(ord($text{$P}) != $packing){
 $packing = 0;
}
     }
   }
   $text = substr($text,0,strlen($text) - $packing);
?>
And to pad a string that you intend to decrypt with .NET, just add the chr() value of the number of padding bytes:
<?php
   $block = mcrypt_get_block_size('tripledes', 'cbc');
   $len = strlen($dat);
   $padding = $block - ($len % $block);
   $dat .= str_repeat(chr($padding),$padding);
?>
That's all there is to it.
Knowing this, you can encrypt, decrypt, and duplicate exactly any .NET 3DES behaviour in PHP.


cleong

Note that the key need to be a binary string--not a hex string. A 128-bit key would be 16 characters long, for example.
Use the pack() function to quickly convert a hex string into the actual binary data:
$key_hex = '66e94bd4ef8a2c3b884cfa59ca342b2e';
$key_bin = pack('H*', $key_hex);
$pt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key_bin, $et, MCRYPT_MODE_ECB);


stonecypher

Most of the user-written cipher examples here are badly broken, and there are a few cases where the manual says things that are outright incorrect, such as that it's "safe to transmit the initialization vector in plaintext" (this is incorrect: see Ciphers By Ritter, http://www.ciphersbyritter.com/GLOSSARY.HTM#IV ,  for details.)
mcrypt itself is perfectly safe, but correct and therefore safe usage is inobvious.  It is important to use a cryptographic library correctly; a simple usage error, even when it produces results that can be unpacked at the other side, can render a strong algorithm completely useless.
The initialization vector must be permuted with a recoverable noise source (an arbitrary md5 hash is acceptable, since it's just a fake OTP and its origin contents are wholly unimportant.)
Passwords should be remade with a salted one-way hash (md5 is again acceptable even though it's been damaged, since the only thing you could recover from a cracked md5 hash is the source data to generate the password, which is useless.)
It's important to use a sane block mode (OFB is unsafe for almost all algorithms; never use it.  Prefer CBC in all cases except where you need to deal with a degraded signal and cannot retransmit.)
A correct usage example is actually pretty long and needs a lot of explanation, so I developed a safe wrapper library which doesn't constrain usage and which comments itself very heavily.  It's appropriate for use or for learning.  Please see my blog for details on Stone PHP SafeCrypt:
http://blog.sc.tri-bit.com/archives/101


ale_ferrer

Mcript - Dot NET - 3DES problem.
This is a solution for the 3DES algorithm's problem in his interaction with .NET TripleDESCryptoServiceProvider (System.Security.Cryptography), CBC mode,  because the key is completed to 192bits and the text is padded.
So, we has two problems:
          - The key's completion  was posted by "jesse at pctest dot com".
          - The text padding also posted by him, but the completion is a little different. The padding bytes are 0x01 to 0x08 because completed to 8 bytes blocks. If your text have a whole number of 8 bytes blocks, the algorithm add other block with padded bytes (0x08).
This is a function to encrypt a text in a equal form that the Dot NET algorithm:
<?PHP
function encryptNET3DES($key, $vector, $text){
   $td = mcrypt_module_open (MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
   // Complete the key
   $key_add = 24-strlen($key);
   $key .= substr($key,0,$key_add);
   // Padding the text
   $text_add = strlen($text)%8;
   for($i=$text_add; $i<8; $i++){
       $text .= chr(8-$text_add);
   }
   mcrypt_generic_init ($td, $key, $vector);
   $encrypt64 = mcrypt_generic ($td, $text);
   mcrypt_generic_deinit($td);
   mcrypt_module_close($td);
// Return the encrypt text in 64 bits code
   return $encrypt64;
}
?>


dylan

I wasn't too impressed with the suggested functions/classes for using mcrypt, so I wrote my own class.  The encypted output is base64 encoded so it can be used in URLs, emails, etc.  MCRYPT_RIJNDAEL_256 is probably too secure for most uses, using a less secure algorithm should mean that the encryption will be faster and the encrypted output shorter (make sure to update iv_size in mcrypt_create_iv() and key length to match the new algorithm).  If you are going to use only 1 passphrase, you should define it inside __construct($this->securekey) instead of when creating the object. Keep the class in a separate include file which is only readable by your webserver (or whatever needs it) for added security.
<?php
class Cipher {
private $securekey, $iv;
function __construct($textkey) {
$this->securekey = hash('sha256',$textkey,TRUE);
$this->iv = mcrypt_create_iv(32);
}
function encrypt($input) {
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->securekey, $input, MCRYPT_MODE_ECB, $this->iv));
}
function decrypt($input) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB, $this->iv));
}
}
$cipher = new Cipher('secret passphrase');
$encryptedtext = $cipher->encrypt("hide me");
echo "->encrypt = $encryptedtext<br />";
$decryptedtext = $cipher->decrypt($encryptedtext);
echo "->decrypt = $decryptedtext<br />";
var_dump($cipher);
?>


anonymous

I should mention that ECB mode ignores the IV, so it is misleading to show an example using both MCRYPT_MODE_ECB and an IV (the example in the manual shows the same thing).  Also, it's important to know that ECB is useful for random data, but structured data should use a stronger mode like MCRYPT_MODE_CBC
Also, rtrim($decryptedtext, "\0") would be a better option to remove NULL padding than my lazy trim()...


davidwhthomas

I forgot to add the sample usage for encrypting and decrypting cookies:
Set encrypted cookie:
<?php
$time = time()+60*60*24*30*12; //store cookie for one year
setcookie('cookie_name', encryptCookie('cookie_value'),$time,'/');
?>
Get encrypted cookie value:
<?php
$cookie_value = decryptCookie($_COOKIE['cookie_name']);
?>
hope it helps.


d a v i d w h t h o m a s @ g m a i l

Here's two simple functions to encrypt and decrypt a string:
function encryptData($value){
  $key = "top secret key";
  $text = $value;
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
  return $crypttext;
}
function decryptData($value){
  $key = "top secret key";
  $crypttext = $value;
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);
  return trim($decrypttext);
}


davidwhthomas

And two more similar functions for encrypting and decrypting cookies:
<?php
function encryptCookie($value){
  if(!$value){return false;}
  $key = 'The Line Secret Key';
  $text = $value;
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
  return trim(base64_encode($crypttext)); //encode for cookie
}
function decryptCookie($value){
  if(!$value){return false;}
  $key = 'The Line Secret Key';
  $crypttext = base64_decode($value); //decode cookie
  $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);
  return trim($decrypttext);
}
?>


alexandrub83

A class to encrypt, decrypt data! if you have problems with using it please visit my site http://www.alexandrub.tk and mail me using Contact section! I use it to encrypt POST and GET data! I don't remember his name but thanks to how recognize his code in the binFromHex function!
<?php
//copyright www.alexandrub.tk
//ver 1.00
class cript
{
var $key;
var $td;
var $time4keyToChange;
var $iv;
function cript($aKey='time',$aTime4keyToChange=3600)
{
$this->time4keyToChange=$aTime4keyToChange;
if($aKey!='time')
  {
  $this->key=$aKey."&".intval(time()/$this->time4keyToChange);
  }
  else
  {
  $this->key=intval(time()/$this->time4keyToChange);
  }
$this->td = MCRYPT_RIJNDAEL_256;
$this->iv = "qe3jigneqfrgnqw2egfmas4qetjkn5lg";
}
function hexFromBin($data)
{
return bin2hex($data);
}
function binFromHex($data)
{
$len = strlen($data);
return pack("H" . $len, $data);
}
function criptData($data)
{
return $this->hexFromBin(mcrypt_encrypt($this->td, $this->key, $data, MCRYPT_MODE_CBC, $this->iv));
}
function decriptData($eData)
{
return trim(mcrypt_decrypt($this->td, $this->key, $this->binFromHex($eData), MCRYPT_MODE_CBC, $this->iv));
}
}
return true;
?>


Change Language


Follow Navioo On Twitter
mcrypt_cbc
mcrypt_cfb
mcrypt_create_iv
mcrypt_decrypt
mcrypt_ecb
mcrypt_enc_get_algorithms_name
mcrypt_enc_get_block_size
mcrypt_enc_get_iv_size
mcrypt_enc_get_key_size
mcrypt_enc_get_modes_name
mcrypt_enc_get_supported_key_sizes
mcrypt_enc_is_block_algorithm_mode
mcrypt_enc_is_block_algorithm
mcrypt_enc_is_block_mode
mcrypt_enc_self_test
mcrypt_encrypt
mcrypt_generic_deinit
mcrypt_generic_end
mcrypt_generic_init
mcrypt_generic
mcrypt_get_block_size
mcrypt_get_cipher_name
mcrypt_get_iv_size
mcrypt_get_key_size
mcrypt_list_algorithms
mcrypt_list_modes
mcrypt_module_close
mcrypt_module_get_algo_block_size
mcrypt_module_get_algo_key_size
mcrypt_module_get_supported_key_sizes
mcrypt_module_is_block_algorithm_mode
mcrypt_module_is_block_algorithm
mcrypt_module_is_block_mode
mcrypt_module_open
mcrypt_module_self_test
mcrypt_ofb
mdecrypt_generic
eXTReMe Tracker