PHP
downloads | documentation | faq | getting help | mailing lists | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

mcrypt_cbc> <Mcrypt
Last updated: Fri, 22 Aug 2008

view this page in

Mcrypt Functions

Table of Contents



mcrypt_cbc> <Mcrypt
Last updated: Fri, 22 Aug 2008
 
add a note add a note User Contributed Notes
Mcrypt Functions
Rafael M. Salvioni
27-Nov-2008 02:26
The follow function is a implementation of the RC4 cypher algorithm in pure PHP code.

The function is used to encrypt and decrypt data.

<?php
/**
 * Crypt/decrypt strings with RC4 stream cypher algorithm.
 *
 * @param string $key Key
 * @param string $data Encripted/pure data
 * @see   http://pt.wikipedia.org/wiki/RC4
 * @return string
 */
function rc4($key, $data)
{
   
// Store the vectors "S" has calculated
   
static $SC;
   
// Function to swaps values of the vector "S"
   
$swap = create_function('&$v1, &$v2', '
        $v1 = $v1 ^ $v2;
        $v2 = $v1 ^ $v2;
        $v1 = $v1 ^ $v2;
    '
);
   
$ikey = crc32($key);
    if (!isset(
$SC[$ikey])) {
       
// Make the vector "S", basead in the key
       
$S    = range(0, 255);
       
$j    = 0;
       
$n    = strlen($key);
        for (
$i = 0; $i < 255; $i++) {
           
$char  = ord($key{$i % $n});
           
$j     = ($j + $S[$i] + $char) % 256;
           
$swap($S[$i], $S[$j]);
        }
       
$SC[$ikey] = $S;
    } else {
       
$S = $SC[$ikey];
    }
   
// Crypt/decrypt the data
   
$n    = strlen($data);
   
$data = str_split($data, 1);
   
$i    = $j = 0;
    for (
$m = 0; $m < $n; $m++) {
       
$i        = ($i + 1) % 256;
       
$j        = ($j + $S[$i]) % 256;
       
$swap($S[$i], $S[$j]);
       
$char     = ord($data[$m]);
       
$char     = $S[($S[$i] + $S[$j]) % 256] ^ $char;
       
$data[$m] = chr($char);
    }
    return
implode('', $data);
}
?>
artem at it-nt dot ru
29-May-2008 10:25
And some code for LM hash:

<?php
function LMhash($string)
{
   
$string = strtoupper(substr($string,0,14));

   
$p1 = LMhash_DESencrypt(substr($string, 0, 7));
   
$p2 = LMhash_DESencrypt(substr($string, 7, 7));

    return
strtoupper($p1.$p2);
}

function
LMhash_DESencrypt($string)
{
   
$key = array();
   
$tmp = array();
   
$len = strlen($string);

    for (
$i=0; $i<7; ++$i)
       
$tmp[] = $i < $len ? ord($string[$i]) : 0;

   
$key[] = $tmp[0] & 254;
   
$key[] = ($tmp[0] << 7) | ($tmp[1] >> 1);
   
$key[] = ($tmp[1] << 6) | ($tmp[2] >> 2);
   
$key[] = ($tmp[2] << 5) | ($tmp[3] >> 3);
   
$key[] = ($tmp[3] << 4) | ($tmp[4] >> 4);
   
$key[] = ($tmp[4] << 3) | ($tmp[5] >> 5);
   
$key[] = ($tmp[5] << 2) | ($tmp[6] >> 6);
   
$key[] = $tmp[6] << 1;
   
   
$is = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
   
$iv = mcrypt_create_iv($is, MCRYPT_RAND);
   
$key0 = "";
   
    foreach (
$key as $k)
       
$key0 .= chr($k);
   
$crypt = mcrypt_encrypt(MCRYPT_DES, $key0, "KGS!@#$%", MCRYPT_MODE_ECB, $iv);

    return
bin2hex($crypt);
}
?>

Some optimization?
EllisGL
08-May-2008 08:58
mre's aes_128_decrypt function was outputting trash at the end. here's my fix.

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);

  preg_match('/([\x20-\x7E]*)/',mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, pack("H*", $encrypted_text), MCRYPT_MODE_ECB, $iv), $a);
  return $a[0];
 } // End of function
matrix dot epokh at gmail dot com
21-Apr-2008 08:21
Using the decrypt funciont of the Pear class Crypt_Blowfish, the decrypted text must be cleaned from null characters (this happen when the text size is not a multiple of the cbc block size). So the correct code should be like:

11 $plaintext = $bf->decrypt($encrypted);
12     if (PEAR::isError($plaintext)) {
13         echo $plaintext->getMessage();
14         exit;
15     }
16     // Encrypted text is padded prior to encryption
17     // so you may need to trim the decrypted result.
18     echo 'plain text: ' . trim($plaintext,"\0");
phpknights at pookmail dot com
01-Feb-2008 11:18
The Pear class Crypt/Blowfish.php will use the mcrypt module if available but the mcrypt module is not required.

Some very easy Pear and example pseudocode to protect your data by encrypting your databases with a one-way hash and blowfish symmetric encryption.
http://en.wikibooks.org/wiki/Cryptography/Database_protection

Using a one-way hash and blowfish symmetric encryption.
1. Insert a record of John Doe in an encrypted database.
2. Get the encrypted record of user John Doe and decrypt the data.

1. Insert a record of John Doe in an encrypted database.
<?php

       
require_once("Crypt/Blowfish.php"); // a Pear class

       
$aRecord['email']       =       "johndoe@anisp.localhost"; // The Primary key
       
$aRecord['name']        =       "John Doe";
       
$aRecord['creditnr']    =       "0192733652342" ;

       
// crypt - one-way encryption
       
$cipher_key = crypt( $aRecord['email'] , "AN_SECRET_COMPANY_SALT");

       
$bf = new Crypt_Blowfish('ecb');
       
$bf->setKey( $cipher_key );

       
// crypt_blowfish symmetric encryption to encrypt the data
       
$aRecord['email']       = $bf->encrypt( $aRecord['email'] );
       
$aRecord['name']        = $bf->encrypt( $aRecord['name'] );
       
$aRecord['creditnr']    = $bf->encrypt( $aRecord['creditnr'] );

       
$result = sqlInsert( $aRecord ) ;
?>

2. Get the encrypted record of user John Doe and decrypt the data.
<?php

       
require_once("Crypt/Blowfish.php");  // a Pear class

       
$primary_key = "johndoe@anisp.localhost";

       
// crypt - one-way encryption
       
$cipher_key = crypt$primary_key , "AN_SECRET_COMPANY_SALT");

       
$bf = new Crypt_Blowfish('ecb');
       
$bf->setKey( $cipher_key );

       
// crypt_blowfish symmetric encryption to ecrypt the primary key for a sql select
       
$select_key = $bf->encrypt$primary_key ) ;

       
$aRecord = sqlSelectWithPKEY( $select_key );

       
// crypt_blowfish symmetric encryption to decrypt the data
       
$aRecord['email']       = $bf->decrypt( $aRecord['email'] );
       
$aRecord['name']        = $bf->decrypt( $aRecord['name'] );
       
$aRecord['creditnr']    = $bf->decrypt( $aRecord['creditnr'] );
?>

Thanks for reading this.
Kevin
23-Jan-2008 07:37
Solved Problem:

when compiling php --with-mcrypt, phpinfo() says, that mcrypt ist enabled, but
"Supported ciphers none" and
"Supported modes none"

In order to get mcrypt to work in php, you have to configure and compile the libmcrypt source package with the following options:
./configure --disable-posix-threads --enable-dynamic-loading
mre (at) reinhardt (dot) info
26-Oct-2007 04:25
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
linusyong at gmail dot com
06-Oct-2007 02:15
Interop Between PHP and Java URLs has changed to:

http://propaso.com/blog/?p=7 (Part 4) it is linked to Part 1, 2 and 3.
Ivan Frederiks
28-Apr-2007 05:03
To enable mcrypt extension under Windows you need to:
1) uncomment line "extension=php_mcrypt.dll" in php.ini
2) download libmcrypt.dll from http://files.edin.dk/php/win32/mcrypt/ 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!!!)

P.S.
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.
linusyong at gmail dot com
12-Mar-2007 01:51
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
http://www.propaso.com/blog/
2007/01/27/aes-interop-between-php-and-java/

Part 2 - Encrypt Using Java / Decrypt Using PHP
http://www.propaso.com/blog/
2007/03/12/aes-interop-between-php-and-java
-part-2-working-the-other-way-around/

P/S: sorry to break the lines for the URL again.
terry200382 at gmail dot com
08-Jan-2007 06:00
To have the same result in Java and PHP with the BouncyCastle library :

/*********
     Java
**********/

import java.security.*;
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());
            System.out.println(asHex(outText));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    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("0");
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }

    public static void main(String[] args) {
        try {
            crypter("password");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/********
     PHP
*********/

<?php
    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);
?>
mwe at icomedias dot com
05-Jan-2007 02:56
>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.
duerra_NOT_THIS_ at pushitlive dot net
20-Sep-2006 10:56
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);
   
   
$key = 'YOUR SECRET KEY HERE';
   
$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);
   
mcrypt_generic_deinit($td);
   
mcrypt_module_close($td);
   
$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);
}
?>
stonecypher at gmail dot como
10-Sep-2006 09:40
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.  http://www.ciphersbyritter.com/GLOSSARY.HTM#IV )

For a *safe* PHP mcrypt wrapper, see Stone PHP SafeCrypt.

http://blog.sc.tri-bit.com/archives/101
pixelchutes AT gmail DOT com
07-Sep-2006 04:49
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.
rolf at winmutt dot com
10-Mar-2006 10:19
mysql AES_ENCRYPT() compatibly function for PHP :

function mysql_aes_encrypt($val,$ky) {
    $mode=MCRYPT_MODE_ECB;   
    $enc=MCRYPT_RIJNDAEL_128;
    $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.
vincent at verbrugh dot nl
01-Mar-2006 11:55
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.
Jerry Hathaway
17-Feb-2006 08:23
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:
http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
triptripon at gmail dot com
05-Feb-2006 01:28
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
jevon at jevon dot org
09-Nov-2005 12:23
To get encryption/decryption working between Delphi and PHP, we used the code available on http://www.cityinthesky.co.uk/cryptography.html . Very helpful.
coz AT metamule D0T com
04-Nov-2005 03:15
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));
            $result.=$char;
        }
        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
joseph-at-digiweb-dot-net-dot-nz
31-Oct-2005 03:22
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.
amiller of connext point net
26-Oct-2005 08:55
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.
torcuato
16-Sep-2005 12:28
There seems to be an error on the list of ciphers supported by the mcrypt extension.

MCRYPT_3DES should be MCRYPT_TRIPLEDES
paul dot lewis at absolutegenius dot co dot uk
13-Jul-2005 06:33
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.
rg at rg dot mejoramos dot com
24-Jun-2005 01:59
Master [thilo-at-hardtware.de], (First Post)

Much thanks by you script.

Now i happy. :-)

Maybe - lines:

<?php
   
function you($string,$key,$a){
    if(empty(
$a))$string=base64_decode($string);
   
$salida='';
    for(
$i=0;$i<strlen($string);$i++){
   
$char=substr($string,$i,1);
   
$keychar=substr($key,($i%strlen($key))-1,1);
    if(
$a)$char=chr(ord($char)+ord($keychar));
    else
$char=chr(ord($char)-ord($keychar));
   
$salida.=$char;
    }if(
$a)$salida=base64_encode($salida);
    return
$salida;}

     
$a='thilo-at-hardtware.de';
    echo
you($a,'xs:a/55p;',1);
   
$b='r+DcptBclqmdo9nlntWmlqfVadzY';
    echo
'<hr>';
    echo
you($b,'xs:a/55p;',0);
exit;
?>Thanks newly.

Regards from CO
MGTech
20-May-2005 10:02
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.
thilo-at-hardtware.de
29-Apr-2005 10:37
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.

<?php
 
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));
     
$result.=$char;
    }

    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));
     
$result.=$char;
    }

    return
$result;
  }

?>
IRLCoder
24-Mar-2005 12:13
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.=" ";
           $i--;
       }
   }
IRLCoder
23-Mar-2005 11:12
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.=" ";
            $i--;
        }
    }

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.
davisd50 at yahoo dot com
18-Mar-2005 06:37
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.
GMScribe
05-Mar-2005 01:58
TO:
16-Feb-2005 01:53

No key is ever truely random, thus it is breakable.
php at stock-consulting dot com
16-Feb-2005 03:53
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.
amiller of connext point net
20-Dec-2004 08:03
"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 --
Jurgen Schwietering
23-Nov-2004 11:20
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.
Anonymous
20-Nov-2004 06:18
Or, if you don't have the mcrypt library, you can just use these functions:

<?php
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));
$result.=$char;
}
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));
$result.=$char;
}
return
$result;
}
?>

It's very simple encryption, but as long as the key stays secret, very powerful.
emaher at newbay dot com
05-Nov-2004 06:37
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
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

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());
Jan Drda <yan at yan dot cz>
16-Oct-2004 04:24
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 http://www.yan.cz/brutuslib/. Hoping it helps somebody.
Moises Deniz Aleman
24-Aug-2004 02:48
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.

<?PHP
/* 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);
 
mcrypt_generic_deinit($td);
 
 
// close the module
 
mcrypt_module_close($td);

 
/* 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 */
 
mcrypt_generic_end($td);
 
mcrypt_module_close($td);
 }
 
 if (
strncmp($p_t, $plain_text, strlen($plain_text)) == 0) {
   return
TRUE;
 } else {
   return
FALSE;
 }
 }

// function call:
@mcrypt_check_sanity();
?>
wagner at cesnet dot cz
16-Aug-2004 07:38
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 http://icebearsoft.euweb.cz/php/
Wilmo
11-Aug-2004 05:54
Changing the function as such seems to greatly help.
<?php
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:
<?php
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
http://www.php.net/manual/en/function.mcrypt-create-iv.php

Cheers,
Wil
Wilmo
11-Aug-2004 05:16
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.
Thanks,
Wil

Here is the code I am using to test the algorithm:

<head><title>Encryption</title>
</head>
<body>
<?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>
</table>
<input type=submit>
</form>

<?php
if(!empty($_REQUEST['input'])){
   
$encrypted=encrypt($_REQUEST['input']);
   
$decrypted=decrypt($encrypted);

    echo
"Encrypted : '$encrypted' Decrypted: '$decrypted' <BR>";
}

$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;
 }
?>

</body>
</html>
dzelko at hotmail dot com
14-May-2004 10:11
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.
Deek Starr
22-Apr-2004 01:16
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
http://ftp.emini.dk/pub/php/win32/mcrypt/libmcrypt.dll

php_mycrypt.dll       14-Jan-2004 5:34    36.8k
From the v4.3.6 windows zip distribution of php.
http://www.php.net/get/php-4.3.6-Win32.zip/from/a/mirror

My assumption is that the new IIS 6 should use the new libmcrypt where IIS <= 5 should use the older version.

[ Hope that helps ]
robert at peakepro dot com
03-Mar-2004 12:59
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.

<?PHP
/* 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";
        
mcrypt_module_close($td);
    }
 }
 }

// 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);
 
mcrypt_generic_deinit($td);
 
 
// close the module
 
mcrypt_module_close($td);

 
/* 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 */
 
mcrypt_generic_end($td);
 
mcrypt_module_close($td);
 }
 
 if (
strncmp($p_t, $plain_text, strlen($plain_text)) == 0) {
    return
TRUE;
 } else {
    return
FALSE;
 }
 }

// function call:
mcrypt_check_sanity();
?>

Apologies for any confusion the previous version may have caused. The only working mode listed was ecb, since it does not use an IV.
groundzero at zuavra dot net
09-Jan-2004 03:08
If you've ever compiled PHP from source (any version)