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

PHP : Function Reference : Mcrypt Encryption Functions

Mcrypt Encryption Functions


This is an interface to the mcrypt library, which supports a wide variety of block algorithms such as DES, TripleDES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2 and GOST in CBC, OFB, CFB and ECB cipher modes. Additionally, it supports RC6 and IDEA which are considered "non-free".


These functions work using » mcrypt. To use it, download libmcrypt-x.x.tar.gz from » and follow the included installation instructions. Windows users will find all the needed compiled mcrypt binaries at »

As of PHP 5.0.0 you will need libmcrypt Version 2.5.6 or greater.

If you linked against libmcrypt 2.4.x or higher, the following additional block algorithms are supported: CAST, LOKI97, RIJNDAEL, SAFERPLUS, SERPENT and the following stream ciphers: ENIGMA (crypt), PANAMA, RC4 and WAKE. With libmcrypt 2.4.x or higher another cipher mode is also available; nOFB.


You need to compile PHP with the --with-mcrypt[=DIR] parameter to enable this extension. DIR is the mcrypt install directory. Make sure you compile libmcrypt with the option --disable-posix-threads.

Runtime Configuration

The behaviour of these functions is affected by settings in php.ini.

Table 169. Mcrypt configuration options

Name Default Changeable Changelog
mcrypt.algorithms_dir NULL PHP_INI_ALL Available since PHP 4.0.2.
mcrypt.modes_dir NULL PHP_INI_ALL Available since PHP 4.0.2.

For further details and definitions of the PHP_INI_* constants, see the Appendix I, php.ini directives.

Resource Types

mcrypt_module_open() returns an encryption descriptor.

Predefined Constants

The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime.

Mcrypt can operate in four block cipher modes (CBC, OFB, CFB, and ECB). If linked against libmcrypt-2.4.x or higher the functions can also operate in the block cipher mode nOFB and in STREAM mode. Below you find a list with all supported encryption modes together with the constants that are defines for the encryption mode. For a more complete reference and discussion see Applied Cryptography by Schneier (ISBN 0-471-11709-9).

  • MCRYPT_MODE_ECB (electronic codebook) is suitable for random data, such as encrypting other keys. Since data there is short and random, the disadvantages of ECB have a favorable negative effect.
  • MCRYPT_MODE_CBC (cipher block chaining) is especially suitable for encrypting files where the security is increased over ECB significantly.
  • MCRYPT_MODE_CFB (cipher feedback) is the best mode for encrypting byte streams where single bytes must be encrypted.
  • MCRYPT_MODE_OFB (output feedback, in 8bit) is comparable to CFB, but can be used in applications where error propagation cannot be tolerated. It's insecure (because it operates in 8bit mode) so it is not recommended to use it.
  • MCRYPT_MODE_NOFB (output feedback, in nbit) is comparable to OFB, but more secure because it operates on the block size of the algorithm.
  • MCRYPT_MODE_STREAM is an extra mode to include some stream algorithms like WAKE or RC4.

Some other mode and random device constants:

MCRYPT_RAND (integer)

Mcrypt ciphers

Here is a list of ciphers which are currently supported by the mcrypt extension. For a complete list of supported ciphers, see the defines at the end of mcrypt.h. The general rule with the mcrypt-2.2.x API is that you can access the cipher from PHP with MCRYPT_ciphername. With the libmcrypt-2.4.x and libmcrypt-2.5.x API these constants also work, but it is possible to specify the name of the cipher as a string with a call to mcrypt_module_open().

  • MCRYPT_ARCFOUR_IV (libmcrypt > 2.4.x only)
  • MCRYPT_ARCFOUR (libmcrypt > 2.4.x only)
  • MCRYPT_DES_COMPAT (libmcrypt 2.2.x only)
  • MCRYPT_ENIGMA (libmcrypt > 2.4.x only, alias for MCRYPT_CRYPT)
  • MCRYPT_IDEA (non-free)
  • MCRYPT_LOKI97 (libmcrypt > 2.4.x only)
  • MCRYPT_MARS (libmcrypt > 2.4.x only, non-free)
  • MCRYPT_PANAMA (libmcrypt > 2.4.x only)
  • MCRYPT_RIJNDAEL_128 (libmcrypt > 2.4.x only)
  • MCRYPT_RIJNDAEL_192 (libmcrypt > 2.4.x only)
  • MCRYPT_RIJNDAEL_256 (libmcrypt > 2.4.x only)
  • MCRYPT_RC4 (libmcrypt 2.2.x only)
  • MCRYPT_RC6 (libmcrypt > 2.4.x only)
  • MCRYPT_RC6_128 (libmcrypt 2.2.x only)
  • MCRYPT_RC6_192 (libmcrypt 2.2.x only)
  • MCRYPT_RC6_256 (libmcrypt 2.2.x only)
  • MCRYPT_SAFERPLUS (libmcrypt > 2.4.x only)
  • MCRYPT_SERPENT(libmcrypt > 2.4.x only)
  • MCRYPT_SERPENT_128 (libmcrypt 2.2.x only)
  • MCRYPT_SERPENT_192 (libmcrypt 2.2.x only)
  • MCRYPT_SERPENT_256 (libmcrypt 2.2.x only)
  • MCRYPT_SKIPJACK (libmcrypt > 2.4.x only)
  • MCRYPT_TEAN (libmcrypt 2.2.x only)
  • MCRYPT_TRIPLEDES (libmcrypt > 2.4.x only)
  • MCRYPT_TWOFISH (for older mcrypt 2.x versions, or mcrypt > 2.4.x )
  • MCRYPT_TWOFISH128 (TWOFISHxxx are available in newer 2.x versions, but not in the 2.4.x versions)
  • MCRYPT_WAKE (libmcrypt > 2.4.x only)
  • MCRYPT_XTEA (libmcrypt > 2.4.x only)

You must (in CFB and OFB mode) or can (in CBC mode) supply an initialization vector (IV) to the respective cipher function. The IV must be unique and must be the same when decrypting/encrypting. With data which is stored encrypted, you can take the output of a function of the index under which the data is stored (e.g. the MD5 key of the filename). Alternatively, you can transmit the IV together with the encrypted data (see chapter 9.3 of Applied Cryptography by Schneier (ISBN 0-471-11709-9) for a discussion of this topic).


Mcrypt can be used to encrypt and decrypt using the above mentioned ciphers. If you linked against libmcrypt-2.2.x, the four important mcrypt commands (mcrypt_cfb(), mcrypt_cbc(), mcrypt_ecb(), and mcrypt_ofb()) can operate in both modes which are named MCRYPT_ENCRYPT and MCRYPT_DECRYPT, respectively.

Example 1288. Encrypt an input value with TripleDES under 2.2.x in ECB mode

= "this is a secret key";
$input = "Let us meet at 9 o'clock at the secret place.";

$encrypted_data = mcrypt_ecb (MCRYPT_3DES, $key, $input, MCRYPT_ENCRYPT);

This example will give you the encrypted data as a string in $encrypted_data.

If you linked against libmcrypt 2.4.x or 2.5.x, these functions are still available, but it is recommended that you use the advanced functions.

Example 1289. Encrypt an input value with TripleDES under 2.4.x and higher in ECB mode

= "this is a secret key";
$input = "Let us meet at 9 o'clock at the secret place.";

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $input);

This example will give you the encrypted data as a string in $encrypted_data. For a full example see mcrypt_module_open().

Table of Contents

mcrypt_cbc — Encrypt/decrypt data in CBC mode
mcrypt_cfb — Encrypt/decrypt data in CFB mode
mcrypt_create_iv — Create an initialization vector (IV) from a random source
mcrypt_decrypt — Decrypts crypttext with given parameters
mcrypt_ecb — Deprecated: Encrypt/decrypt data in ECB mode
mcrypt_enc_get_algorithms_name — Returns the name of the opened algorithm
mcrypt_enc_get_block_size — Returns the blocksize of the opened algorithm
mcrypt_enc_get_iv_size — Returns the size of the IV of the opened algorithm
mcrypt_enc_get_key_size — Returns the maximum supported keysize of the opened mode
mcrypt_enc_get_modes_name — Returns the name of the opened mode
mcrypt_enc_get_supported_key_sizes — Returns an array with the supported keysizes of the opened algorithm
mcrypt_enc_is_block_algorithm_mode — Checks whether the encryption of the opened mode works on blocks
mcrypt_enc_is_block_algorithm — Checks whether the algorithm of the opened mode is a block algorithm
mcrypt_enc_is_block_mode — Checks whether the opened mode outputs blocks
mcrypt_enc_self_test — This function runs a self test on the opened module
mcrypt_encrypt — Encrypts plaintext with given parameters
mcrypt_generic_deinit — This function deinitializes an encryption module
mcrypt_generic_end — This function terminates encryption
mcrypt_generic_init — This function initializes all buffers needed for encryption
mcrypt_generic — This function encrypts data
mcrypt_get_block_size — Get the block size of the specified cipher
mcrypt_get_cipher_name — Get the name of the specified cipher
mcrypt_get_iv_size — Returns the size of the IV belonging to a specific cipher/mode combination
mcrypt_get_key_size — Get the key size of the specified cipher
mcrypt_list_algorithms — Get an array of all supported ciphers
mcrypt_list_modes — Get an array of all supported modes
mcrypt_module_close — Close the mcrypt module
mcrypt_module_get_algo_block_size — Returns the blocksize of the specified algorithm
mcrypt_module_get_algo_key_size — Returns the maximum supported keysize of the opened mode
mcrypt_module_get_supported_key_sizes — Returns an array with the supported keysizes of the opened algorithm
mcrypt_module_is_block_algorithm_mode — Returns if the specified module is a block algorithm or not
mcrypt_module_is_block_algorithm — This function checks whether the specified algorithm is a block algorithm
mcrypt_module_is_block_mode — Returns if the specified mode outputs blocks or not
mcrypt_module_open — Opens the module of the algorithm and the mode to be used
mcrypt_module_self_test — This function runs a self test on the specified module
mcrypt_ofb — Encrypt/decrypt data in OFB mode
mdecrypt_generic — Decrypt data

Code Examples / Notes » ref.mcrypt


Windows IIS Users - Problems installing/using mcrypt and other extensions
I've noticed a lot of users complaining in forums that they have difficult time getting mcrypt extension to function/ finding or installing working .dlls when using IIS:
Easy solution that works well for me: (IIS 6 on Win 2003 Svr and IIS on XP Pro) #customized install later for increased security#
1. Install current stable php version using windows installer #gets php up and running quickly#
2. Download Windows Binary Package
3. Extract Package Library to PHP folder installer generates - overwrite all
4. Edit php.ini as appropriate.  (specifically for mcrypt uncomment mcrypt=php_mcrypt.dll)
No mo' problems.


16-Feb-2005 01:53
No key is ever truely random, thus it is breakable.


To have the same result in Java and PHP with the BouncyCastle library :
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public class tester {
public static void crypter(String password) {
try {
//  -- Install jar "bcprov-jdk14-135.jar" in <install_jdk>/jre/lib/ext/
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("Blowfish/ECB/ZeroBytePadding");
                       // -- Substring is used to have no problem with key length
SecretKeySpec keySpec = new SecretKeySpec(password.substring(0,8).getBytes(), "Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] outText = cipher.doFinal(password.getBytes());
catch (Exception e) {
public static String asHex (byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
return strbuf.toString();
public static void main(String[] args) {
try {
catch (Exception e) {
header("Content-Type: text/plain");
$data = "password";
echo substr($data, 0,8)."\n";
$encrypted_data = mcrypt_ecb(MCRYPT_BLOWFISH, substr($data, 0,8), $data, MCRYPT_ENCRYPT);
echo bin2hex($encrypted_data);


To get encryption/decryption working between Delphi and PHP, we used the code available on . Very helpful.

ivan frederiks

To enable mcrypt extension under Windows you need to:
1) uncomment line "extension=php_mcrypt.dll" in php.ini
2) download libmcrypt.dll from and put it to System32 directory (for example C:\Windows\System32).
Tested on Windows XP+Apache 1.3.37+PHP 4.4.6 (as SAPI module!!!)
I wrote this because I got "Cannot load mcrypt extension. Please check your PHP configuration." from phpMyAdmin when I simply uncommented "extension=php_mcrypt.dll" line.

moises deniz aleman

This is a modified version of a previous script that test the algorithms and modes of mcrypt dll. This new script prints out the result in a table and avoid warnings to be printed.
/* run a self-test through every listed cipher and mode */
function mcrypt_check_sanity() {
$modes = mcrypt_list_modes();
$algorithms = mcrypt_list_algorithms();
echo "<table border=1>";
echo "<tr><td align=center><strong>Algorithm</strong></td align=center><td><strong>Status</strong></td>";
foreach ($modes as $mode) echo "<td align=center><strong>".strtoupper($mode)."</strong></td>";
echo "</tr>";
foreach ($algorithms as $cipher) {
  echo "<tr><td bgcolor=f0f0ff align=left>".strtoupper($cipher)."</td>";
  if(mcrypt_module_self_test($cipher)) {
      print "<td bgcolor=green align=center>OK</td>";
  } else {
      print "<td bgcolor=red align=center>NOT OK</td>";
  foreach ($modes as $mode) {
      if($mode == 'stream') {
          $result = "<td bgcolor=gray align=center>NOT TESTED</td>";
      } else if(mcrypt_test_module_mode($cipher,$mode)) {
            $result = "<td bgcolor=green align=center><strong>OK</strong></td>";
      } else {
            $result = "<td bgcolor=red align=center>NOT OK</td>";
      print $result;
  echo "</tr>";
echo "</table>";
// a variant on the example posted in mdecrypt_generic
function mcrypt_test_module_mode($module,$mode) {
/* Data */
$key = 'this is a very long key, even too long for the cipher';
$plain_text = 'very important data';
/* Open module, and create IV */
$td = mcrypt_module_open($module, '',$mode, '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
/* Initialize encryption handle */
if (mcrypt_generic_init($td, $key, $iv) != -1) {
/* Encrypt data */
$c_t = mcrypt_generic($td, $plain_text);

// close the module
/* Reinitialize buffers for decryption */
/* Open module */
$td = mcrypt_module_open($module, '', $mode, '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$p_t = trim(mdecrypt_generic($td, $c_t)); //trim to remove padding
/* Clean up */

if (strncmp($p_t, $plain_text, strlen($plain_text)) == 0) {
  return TRUE;
} else {
  return FALSE;
// function call:


There seems to be an error on the list of ciphers supported by the mcrypt extension.


The statement that use of the 'generic' functions is 'recommended' in 2.4+ should probably be 'required'.  Having like many others struggled with a "mcrypt module initialization failed" error even when phpinfo() showed mcrypt installed and all its algorithms loaded, I found that:
$key = mcrypt_ecb (MCRYPT_3DES, $magic, $input, MCRYPT_ENCRYPT);
fails, but
$td = mcrypt_module_open (MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, $magic, $iv);
$key = mcrypt_generic ($td, $input);
mcrypt_generic_end ($td);
works fine.  You can't leave out the creation of the IV to the right length, even though ECB doesn't use it (happily, because I want it repeatable).


the encrypted result data maybe binary data and It make errors in sql query.
so use the base64_encode/base64_decode function with mcrypt()
try below


The Algorithm posted by:
Mike Zaccari
29-Jun-2004 03:54
"I'm running PHP 4.3.7 on Apache 2.0.49 on an Xp machine, and after many hours of googling over the internet I found that the easiest way to use the mcrypt function was to do this:"
Thanks for posting this Mike but there seems to be a problem
with your implementation.
On my machine and I suspect others, the output is independent
of the key. I can change the key and this has no effect on
the resulting crypted data. So the input is always encrypted the
same way irregardless of the key and therefore decrypted
with any key.
This would only be secure if an attacker knew nothing about the
algorithm which seems unlikely from an experienced attacker.
I am looking into a fix and will post if resolved.
Does anybody else have this problem? I want to make sure my install is good.
I am running on a gentoo linux box.
Here is the code I am using to test the algorithm:
<?php print_debug_header(1); ?>
<form name=form method=post action='encrypt.php'>
<table align=center>
<TR><TD>Source Text:</TD><TD><input type=text name=input value=<?php echo $_REQUEST['input']; ?>></TD></TR>
<TR><TD>Key:</TD><TD><input type=text name=key value=<?php echo $_REQUEST['key']; ?>></TD></TR>
<input type=submit>
echo "Encrypted : '$encrypted' Decrypted: '$decrypted'
$key = $_REQUEST['key'];

//Encrypt Function
function encrypt($encrypt) {
   global $key;
   $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
   $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt, MCRYPT_MODE_ECB, $iv);
   $encode = base64_encode($passcrypt);
return $encode;

//Decrypt Function
function decrypt($decrypt) {
   global $key;
   $decoded = base64_decode($decrypt);
   $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
   $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_ECB, $iv);
return $decrypted;

jan drda
Sometimes mcrypt library is not aviable e.g. commercial hosting, customer restrictions, etc. Because of these conditions I wrote alternative free synchronous encryption library in pure PHP. It is not so complex as mcrypt, but it is sufficient. Everything including detailed documentation and API description is avaiable at Hoping it helps somebody.


Regarding storing the result on a postgres DB that uses Unicode (follow up to a post below).
You don't need to change the DB's encoding to ASCII.
Simply use BASE64 to encode the result, it's perfectly safe.
use base64_decode before you decrypt.
-- Tomer Levinboim


Re: Just a followup note about mcrypt<-->java interop (have a php app encrypting a string and a java app decrypting it - and vice-versa!)
Sorry, the PHP had a bug and should have been the following:
  $dlen = strlen($data);
  $pad = 16 - fmod($dlen, 16); //change here
  if ($pad > 0) {
      $i = (int)$pad;
      while ($i > 0) {
          $data.=" ";


Please, mind that a XOR Encryption can't compete with a block cipher like AES or IDEA, but if you really want to use a stream cipher the more secure RC4 is the right alternative.
A XOR Encryption is only a bit useful if you encrypt data for private use, otherwise it is a frankly a security risk.


Or, if you don't have the mcrypt library, you can just use these functions:
function Encrypt($string, $key)
$result = '';
for($i=1; $i<=strlen($string); $i++)
$char = substr($string, $i-1, 1);
$keychar = substr($key, ($i % strlen($key))-1, 1);
$char = chr(ord($char)+ord($keychar));
return $result;
function Decrypt($string, $key)
$result = '';
for($i=1; $i<=strlen($string); $i++)
$char = substr($string, $i-1, 1);
$keychar = substr($key, ($i % strlen($key))-1, 1);
$char = chr(ord($char)-ord($keychar));
return $result;
It's very simple encryption, but as long as the key stays secret, very powerful.


mysql AES_ENCRYPT() compatibly function for PHP :
function mysql_aes_encrypt($val,$ky) {
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $ky, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM));
Please note that if the strlen($ky)>16 then this function will not be compatible.


Most of the ciphers 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 for details. )
For a *safe* PHP mcrypt wrapper, see Stone PHP SafeCrypt.


mcrypt_ecb with base64_decode gave some problems, i found out that it had to be chopped to work:


Master [], (First Post)
Much thanks by you script.
Now i happy. :-)
Maybe - lines:
function you($string,$key,$a){
else $char=chr(ord($char)-ord($keychar));
return $salida;}
echo you($a,'xs:a/55p;',1);
echo '<hr>';
echo you($b,'xs:a/55p;',0);
?>Thanks newly.
Regards from CO

steve@itemfront dot ltd dot uk

Just spent a while getting mcrypt support working with php. Used libmcrypt version 2.5.7 with php 4.3.3. Out of the box it just won't work. Configure as follows:
 ./configure --disable-posix-threads --enable-dynamic-loading
php: ( as you can see, it's built for a SunONE server, but that's the easy bit to configure! )
./configure  --with-nsapi=/usr/iplanet/servers --enable-sigchld --with-ldap --with-zlib-dir=/usr/lib --with-mcrypt=<srcdir>/libmcrypt-2.5.7
hth, steve


Just a note about mcrypt<-->java interop (have a php app encrypting a string and a java app decrypting it)
php mcrypt pads the plaintext with spaces until the plaintext is a multiple of the block size (e.g 16 for most symmetric ciphers). These spaces have to be stripped on when decrypting on the java side. Seems to be no other way of using a sensible padding (e.g. with PKCS #5) on the mcrypt side.
The following php and java will interop
$cipher = "rijndael-128";
$mode = "cbc";
echo "CIPHER: $cipher | MODE: $mode\n";
// data,key, iv
$data = "blah";
$key = "01234567890abcdef";
$iv = "fedcba9876543210";
// set up and encyrpt
$td = mcrypt_module_open($cipher, "", $mode, $iv);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $data);
echo bin2hex($encrypted_data);
// tear down
Java side
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec("01234567890abcdef".getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] outText = cipher.doFinal(fromHexString(input));
System.out.println(new String(outText).trim());


Just a followup note about mcrypt<-->java interop (have a php app encrypting a string and a java app decrypting it - and vice-versa!)
it seems that mcrypt pads with nulls (0x00) instead of spaces so to allow the interop to work properly (where both java and php/mcrypt encode strings to the same value) - I padded the PHP strings with spaces first before encrypting and did the same on the Java side - thus the padding was the same on each side and the interop is complete.  Here's sample PHP for padding:
$dlen = strlen($data);
$pad = fmod($dlen, 16);
if ($pad > 0) {
$i = (int)$pad;
while ($i > 0) {
$data.=" ";
and here's the Java padding:
public static String PadString(String in) {
       int slen = (in.length() % 16);
       int i = (16 - slen);
       if ((i > 0) && (i < 16)){
          StringBuffer buf = new StringBuffer(in.length() + i);
          buf.insert(0, in);
          for (i = (16 - slen); i > 0; i--) {
             buf.append(" ");
         return buf.toString();
       else {
          return in;
With trimming on each side for decryption ... all works well.


Interop Between PHP and Java URLs has changed to: (Part 4) it is linked to Part 1, 2 and 3.


If you've ever compiled PHP from source (any version) you may be familiar with the [in]famous MCRYPT_BLOWFISH_128 compilation error that appears when you attempt to compile --with-mcrypt. It occurs often on Debian but not only there. The problem: during compilation, the PHP configure script always assumes that libmcrypt has been built in conjunction with libltdl. Whenever that is not the case, PHP compilation will fail later saying certain headers (such as the above blowfish example) are missing from mcrypt.h (which is misleading, they're not supposed to be there nor looked after if libltdl was properly involved). Solution: make sure your libmcrypt was linked against libltdl before you even start configuring PHP. You can check by running 'ldd' and verifying that libltdl appears in the output. libltdl can be found in libltld[3][-dev] on Debian or in libtool-libs on Red Hat.


If you're going to encrypt data with something like this and store it in postgres.
function encrypt($string, $key){
$result = '';
for($i=1; $i<=strlen($string); $i++){
$char = substr($string, $i-1, 1);
$keychar = substr($key, ($i % strlen($key))-1, 1);
$char = chr(ord($char)+ord($keychar));
return $result;
Make sure when you create your database to set the encoding to SQL_ASCII because you won't be able to store this data in a database that uses UNICODE


If you plan to use Mcrypt Encryption to store encrypted data (e.g. passwords) in a (MySQL) database make sure to set the column to BLOB rather than VARCHAR. Otherwise the data may change which can give unexpected results if you decrypt the value.


If you compiled mcrypt and php without problem, but phpinfo() shows there are no supported ciphers and modes, try to change mode to 755 on libdirs (/usr/local/libmcrypt, /usr/local/libcrypt).


If you are using ECB mode to encrypt it does not seem to use the iv (initialization vector) for much of anything, given the same key it will always decrypt it no matter what the iv is.  If you use CBC mode you must decrypt with the same iv that you encrypted with.
If you use a different iv before decrypting, your decrypt will not work.  IMHO it seems better to use CBC mode than ECB as ECB will always encrypt to the same cipher text given the same plain text  (leaving you open to know plaintext attacks).  CBC uses the random iv which means text encrypts to different things.  You probably could get the same effect from using random keys in ECB mode.
Read that in the Schneier book - Applied Cryptography (ISBN 0-471-11709-9)  This book is a must for anyone seriously using any type of encryption.

paul dot lewis

I've spent the majority of the day attempting to get mcrypt to work under IIS6 with Windows Server 2003 (Web Edition) and PHP 5.0.4
There seems to be some incompatability with enabling certain extensions (mcrypt being one) when you are running PHP as ISAPI in this environment.
The way to solve the problem (the error will be that it cannot load php_mcrypt.dll - access is denied) is to run in CGI. While this isn't supposed to be as good performance wise, if you need the mcrypt support (or Oracle support, too, I believe) then this is the only way I've found to do it.


I was creating a cross-platform (unix + windows) application and ran into some issues with different versions of mcrypt (2.4.x vs 2.5.x) not working with Windows.  After further investigation, I found the following:
Libmcrypt 2.5.7 is not usable with PHP 4.x.

The reason is a very Windows-specific issue.  DLLs are Windows' way of providing shared code - things get loaded once into RAM and are guaranteed identical across all applications that use them.  When an application references a routine/function in a DLL, it may do so either by function name or by reference number.  Referring to a routine by name is considered slow by some people and does slow down the startup of applications that use large numbers of routines in DLLs (applications such as PHP).  Referring to a routine by reference number is very quick but breaks if a new DLL version changes the reference number assignments for its routines.

Libmcrypt 2.5.6 & 7's DLLs do not have the same reference number assignments as old Libmcrypt.dll files did.  Specifically, function 148 (mdecrypt_generic) has been moved in 2.5.6/7 to number 149 due to the addition of the mcrypt_mutex_register function which moved everything above it alphebetically up a reference number.  PHP's php_mcrypt.dll, which provides the PHP language bindings to the low-level Libmcrypt.dll, refers to Libmcrypt.dll's functions by number instead of name.  PHP 4.x's php_mcrypt.dll refers to function 148 while PHP 5.0's php_mcrypt.dll refers to function 149 and notes that PHP 5.0 under Windows can only work with Libmcrypt 2.5.6 and higher (because function 149 in old Libmcrypt is actually the Panama encryption algorithm, not the expected mcrypt_generic routine).

So, unless you can find a PHP 4.x php_mcrypt.dll that has been compiled for Libmcrypt 2.5.6 and higher, PHP 4.x won't be able to decrypt data with Libmcrypt 2.5.7 under Windows.


I posted a link to my blog on AES encryption using PHP and decrypt using Java.  Just wrote a sequel to it to work the other way around (encrypt with Java and decrypt with PHP).
Interop Between PHP and Java using AES:
Part 1 - Encrypt Using PHP / Decrypt Using Java
Part 2 - Encrypt Using Java / Decrypt Using PHP
P/S: sorry to break the lines for the URL again.

I have modified the xor-encryption of Anonymous. It is now returning and eating base64-encoded strings. That's much better for saving and transporting (e.g. saving in a database) the encrypted string.
 function encrypt($string, $key) {
   $result = '';
   for($i=0; $i<strlen($string); $i++) {
     $char = substr($string, $i, 1);
     $keychar = substr($key, ($i % strlen($key))-1, 1);
     $char = chr(ord($char)+ord($keychar));
   return base64_encode($result);
 function decrypt($string, $key) {
   $result = '';
   $string = base64_decode($string);
   for($i=0; $i<strlen($string); $i++) {
     $char = substr($string, $i, 1);
     $keychar = substr($key, ($i % strlen($key))-1, 1);
     $char = chr(ord($char)-ord($keychar));
   return $result;


I have another comment to the script submitted by robert at peakepro dot com. He uses deprecated function mcrypt_generic_end which also closes the module. Subsequent mcrypt_module_close then complains about invalid resource. Moreover, not all combinations of algorith and mode are compatible. It is necessary to check the return value from mcrypt_module_open in order to find whether the module can be open for selected combination. My script also displays some useful information. You can find the full source at my site


Here are my functions to do a 128 bit aes encryption which is transmitted
to the dachser parcel tracking system via url. They expect a true aes
128 bit encryption an process the reqest by a java script. The decrypt
function is just a giveaway.
function aes_128_encrypt($text,$password) {
       $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
       $iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM);
       // The following line was needed because I didn't get the same hex value as expected by forwarding agency
       // I think its their bug
       // Try to remove the line. If it works, too - fine!
       $text .= chr(3).chr(3).chr(3);
       return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $password, $text, MCRYPT_MODE_ECB, $iv));
} // End of function
function aes_128_decrypt($encrypted_text,$password) {
       $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
       $iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM);
       return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, pack("H*", $encrypted_text), MCRYPT_MODE_ECB, $iv);
} // End of function


For those of you that need to use PKCS#5 padding, the mcrypt API's for PHP do not support it.  However, you can DIY using the following:
function encrypt_something($input)
$size = mcrypt_get_block_size('des', 'ecb');
$input = pkcs5_pad($input, $size);

$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
$data = base64_encode($data);
return $data;
function pkcs5_pad ($text, $blocksize)
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
function pkcs5_unpad($text)
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);


For those looking for a mysql_aes_decrypt, I created this method, referencing rolf's aes_encrypt below. Since the aes_encrypt right-pads N * blocksize with any chr( 0 ) to chr( 16 ) (random based on the input string length) we first decrypt the text, then RTrim chr(0 .. 16) depending on its trailing ord() value.
mysql AES_DECRYPT() compatibly function for PHP :
      function mysql_aes_decrypt( $val, $ky )
          $mode = MCRYPT_MODE_ECB;
          $enc = MCRYPT_RIJNDAEL_128;
          $dec = @mcrypt_decrypt($enc, $ky, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM ) );
          return rtrim( $dec, ( ( ord(substr( $dec, strlen( $dec )-1, 1 )) >= 0 and ord(substr( $dec, strlen( $dec )-1, 1 ) ) <= 16 ) ? chr(ord(substr( $dec, strlen( $dec )-1, 1 ))): null) );
Please note that if the strlen($ky)>16 then this function will not be compatible.


For a practical example suitable for encrypting and
validating cookies or passing secure messages,
go to


DEBIAN users: avoid mcrypt installation headaches.
to add mcrypt support to an existing php installation, get root and run
apt-get install php4-mcrypt
restart your webserver, and voilà.


Changing the function as such seems to greatly help.
function encrypt($encrypt) {
   global $key;
   srand((double) microtime() * 1000000); //for sake of MCRYPT_RAND
   $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
   $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt, MCRYPT_MODE_ECB, $iv);
   $encode = base64_encode($passcrypt);
return $encode;
by adding:
srand((double) microtime() * 1000000); //for sake of MCRYPT_RAND
which I guess seeds the encryption routine differently everytime.
Thanks to  robert at peakepro dot com sourced from

jurgen schwietering

Attention when using keys longer than the actual key size (i.e. 160 bit instead of 128 bit).
It will work inbetween PHP scripts, but might cause problems when using openssl or other packages with this integration of mcrypt. Cut them always to the supported size (mcrypt_enc_get_key_size) to avoid sleepless hours.

amiller of connext point net

As regards the whole one-time-pad discussion below, I would also add that any one-time pad scheme which involves the key passing through a computer in any fashion is blown from the very beginning. At best, you have to rely on a less-secure cipher for key transmission; at (far-from-uncommon) worst, your key has been written in the clear to some sectors of the disk (for example, by being swapped out of memory), and awaits only someone with a sector-scanning tool to reveal it.
If you're thinking about Internet security, considering a one-time pad at all, unless you're planning to use one to protect another cipher system's keys for transmission (and probably even then!), is a waste of your time.

deek starr

As per the issue with decrypting (mdecrypt_generic) on iss in windows. My finding as that the new 2004 version works but the 2002 does not.
I'm using WinXP Server 2003 - ISS 6.0 with:
libmcrypt.dll           19-Jan-2004 02:27   163k
php_mycrypt.dll       14-Jan-2004 5:34    36.8k
From the v4.3.6 windows zip distribution of php.
My assumption is that the new IIS 6 should use the new libmcrypt where IIS <= 5 should use the older version.
[ Hope that helps ]


amiller of connext point net is correct. The 'one-time pad' is unbreakable, if used correctly. Correct use requires that:
1. the key length equals or exceeds the data length
2. the key must not be used more than once to encrypt data
3. the key must be truly random.
The last point is a bit of a problem. "Random Number Generator" algorithms are only pseudo-random. Once the attacker finds out which PRNG was used, breaking the encryption becomes easy. Hardware solutions for the generation of random data (like, sampling noise via the sound card input and taking the LSB) have also proven to be of dubious quality.
Violation of point 2 makes the encryption worthless. A known-plaintext attack will reveal the key at once.

jerry hathaway

After benchmarking AES in 256-bit operation, I've concluded that CBC is far faster than OFB.  Using a 14.9 MiB file, on average...
Encrypt in CBC:   1.9 seconds
Encrypt in OFB:   45.7 seconds (same as CFB)
Just reading the file:  ~.53 seconds
After some research, I've concluded that OFB and CFB are slightly more secure than CBC, however I believe the performance difference to be due to an implementation issue.
As a side note on ECB:  As stated in the wiki linked to below, ECB is wholly inadequate.  It not use an IV (whether it was supplied ot MCrypt or not), meaning the same key and plaintext always produce the same ciphertext and it doesn't hide patterns.  The site shows an excellent example of this.
Very useful info:


A further note for those doing interop between PHP and Java:
If you're using the BouncyCastle library on the Java side, then you can use the ZeroBytePadding mode now available in it. Mcrypt pads the data with Nulls rather than spaces....
I've sucessfully done interop using Blowfish/CBC/ZeroBytePadding between PHP and Java this way.


15-Feb-2004 06:17
"I found this nested loop very useful for checking the sanity of my libmcrypt install. It turned out many of the modules weren't working in certain modes. Hopefully this will save someone some frustration:"
I have ammended the mcrypt_check_sanity() function. This is a bug fix: the function was reinitializing the IV, which is unacceptable. Here is the complete, fixed version. Note that 'stream' mode is not tested.
/* run a self-test through every listed cipher and mode */
function mcrypt_check_sanity() {
$modes = mcrypt_list_modes();
$algorithms = mcrypt_list_algorithms();
foreach ($algorithms as $cipher) {
   if(mcrypt_module_self_test($cipher)) {
       print $cipher." ok.<br />\n";
   } else {
       print $cipher." not ok.<br />\n";
   foreach ($modes as $mode) {
       if($mode == 'stream') {
           $result = "not tested";
       } else if(mcrypt_test_module_mode($cipher,$mode)) {
            $result = "ok";
       } else {
            $result = "not ok";
       print $cipher." in mode ".$mode." ".$result."<br />\n";
// a variant on the example posted in mdecrypt_generic
function mcrypt_test_module_mode($module,$mode) {
/* Data */
$key = 'this is a very long key, even too long for the cipher';
$plain_text = 'very important data';
/* Open module, and create IV */
$td = mcrypt_module_open($module, '',$mode, '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
/* Initialize encryption handle */
if (mcrypt_generic_init($td, $key, $iv) != -1) {
/* Encrypt data */
$c_t = mcrypt_generic($td, $plain_text);

// close the module
/* Reinitialize buffers for decryption */
/* Open module */
$td = mcrypt_module_open($module, '', $mode, '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$p_t = trim(mdecrypt_generic($td, $c_t)); //trim to remove padding
/* Clean up */

if (strncmp($p_t, $plain_text, strlen($plain_text)) == 0) {
   return TRUE;
} else {
   return FALSE;
// function call:
Apologies for any confusion the previous version may have caused. The only working mode listed was ecb, since it does not use an IV.


>coz AT metamule D0T com
>04-Nov-2005 02:15
>Make sure when you create your database to set the >encoding to SQL_ASCII because you won't be able to store >this data in a database that uses UNICODE
Not really necessary, simply store the enrypted data in a BYTEA column and it will work fine.

amiller of connext point net

"Anonymous'" comment of Nov 19th refers to an encryption scheme known as a 'one-time pad'. Anonymous forgot to mention that, while it's true the one-time pad is secure as long as the key's kept secret, it's also necessary to avoid reusing keys -- multiple plaintexts encrypted using a single key are insecure, too, because of collisions, and that's why it's called a 'one-time pad'. Hope this helps --

Change Language

Follow Navioo On Twitter
.NET Functions
Apache-specific Functions
Alternative PHP Cache
Advanced PHP debugger
Array Functions
Aspell functions [deprecated]
BBCode Functions
BCMath Arbitrary Precision Mathematics Functions
PHP bytecode Compiler
Bzip2 Compression Functions
Calendar Functions
CCVS API Functions [deprecated]
Class/Object Functions
Classkit Functions
ClibPDF Functions [deprecated]
COM and .Net (Windows)
Crack Functions
Character Type Functions
Cybercash Payment Functions
Credit Mutuel CyberMUT functions
Cyrus IMAP administration Functions
Date and Time Functions
DB++ Functions
Database (dbm-style) Abstraction Layer Functions
dBase Functions
DBM Functions [deprecated]
dbx Functions
Direct IO Functions
Directory Functions
DOM Functions
DOM XML Functions
enchant Functions
Error Handling and Logging Functions
Exif Functions
Expect Functions
File Alteration Monitor Functions
Forms Data Format Functions
Fileinfo Functions
filePro Functions
Filesystem Functions
Filter Functions
Firebird/InterBase Functions
Firebird/Interbase Functions (PDO_FIREBIRD)
FriBiDi Functions
FrontBase Functions
FTP Functions
Function Handling Functions
GeoIP Functions
Gettext Functions
GMP Functions
gnupg Functions
Haru PDF Functions
hash Functions
Hyperwave Functions
Hyperwave API Functions
i18n Functions
IBM Functions (PDO_IBM)
iconv Functions
ID3 Functions
IIS Administration Functions
Image Functions
Imagick Image Library
Informix Functions
Informix Functions (PDO_INFORMIX)
Ingres II Functions
IRC Gateway Functions
PHP / Java Integration
JSON Functions
LDAP Functions
libxml Functions
Lotus Notes Functions
LZF Functions
Mail Functions
Mailparse Functions
Mathematical Functions
MaxDB PHP Extension
MCAL Functions
Mcrypt Encryption Functions
MCVE (Monetra) Payment Functions
Memcache Functions
Mhash Functions
Mimetype Functions
Ming functions for Flash
Miscellaneous Functions
mnoGoSearch Functions
Microsoft SQL Server Functions
Microsoft SQL Server and Sybase Functions (PDO_DBLIB)
Mohawk Software Session Handler Functions
mSQL Functions
Multibyte String Functions
muscat Functions
MySQL Functions
MySQL Functions (PDO_MYSQL)
MySQL Improved Extension
Ncurses Terminal Screen Control Functions
Network Functions
Newt Functions
NSAPI-specific Functions
Object Aggregation/Composition Functions
Object property and method call overloading
Oracle Functions
ODBC Functions (Unified)
ODBC and DB2 Functions (PDO_ODBC)
OpenAL Audio Bindings
OpenSSL Functions
Oracle Functions [deprecated]
Oracle Functions (PDO_OCI)
Output Control Functions
Ovrimos SQL Functions
Paradox File Access
Parsekit Functions
Process Control Functions
Regular Expression Functions (Perl-Compatible)
PDF Functions
PDO Functions
Phar archive stream and classes
PHP Options&Information
POSIX Functions
Regular Expression Functions (POSIX Extended)
PostgreSQL Functions
PostgreSQL Functions (PDO_PGSQL)
Printer Functions
Program Execution Functions
PostScript document creation
Pspell Functions
qtdom Functions
Rar Functions
GNU Readline
GNU Recode Functions
RPM Header Reading Functions
runkit Functions
SAM - Simple Asynchronous Messaging
Satellite CORBA client extension [deprecated]
SCA Functions
SDO Functions
SDO XML Data Access Service Functions
SDO Relational Data Access Service Functions
SESAM Database Functions
PostgreSQL Session Save Handler
Session Handling Functions
Shared Memory Functions
SimpleXML functions
SNMP Functions
SOAP Functions
Socket Functions
Standard PHP Library (SPL) Functions
SQLite Functions
SQLite Functions (PDO_SQLITE)
Secure Shell2 Functions
Statistics Functions
Stream Functions
String Functions
Subversion Functions
Shockwave Flash Functions
Swish Functions
Sybase Functions
TCP Wrappers Functions
Tidy Functions
Tokenizer Functions
Unicode Functions
URL Functions
Variable Handling Functions
Verisign Payflow Pro Functions
vpopmail Functions
W32api Functions
WDDX Functions
win32ps Functions
win32service Functions
xattr Functions
xdiff Functions
XML Parser Functions
XML-RPC Functions
XMLReader functions
XMLWriter Functions
XSL functions
XSLT Functions
YAZ Functions
YP/NIS Functions
Zip File Functions
Zlib Compression Functions
eXTReMe Tracker