Mcrypt 函数
在线手册:中文  英文

mcrypt_encrypt

(PHP 4 >= 4.0.2, PHP 5)

mcrypt_encryptEncrypts plaintext with given parameters

说明

string mcrypt_encrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] )

Encrypts the data and returns it.

参数

cipher

MCRYPT_ciphername 常量中的一个,或者是字符串值的算法名称。

key

The key with which the data will be encrypted. If it's smaller than the required keysize, it is padded with '\0'. It is better not to use ASCII strings for keys.

It is recommended to use the mhash functions to create a key from a string.

data

The data that will be encrypted with the given cipher and mode. If the size of the data is not n * blocksize, the data will be padded with '\0'.

The returned crypttext can be larger than the size of the data that was given by data.

mode

MCRYPT_MODE_modename 常量中的一个,或以下字符串中的一个:"ecb","cbc","cfb","ofb","nofb" 和 "stream"。

iv

在 CBC, CFB, OFB 模式中用于初始化过程,在 STREAM 模式中用于某些算法。如果未提供 IV 并且在某算法中需要,本函数发出一条警告并使用一个全部字节设为 "\0" 的 IV。

返回值

Returns the encrypted data, as a string.

范例

Example #1 mcrypt_encrypt() Example

<?php
    
# --- ENCRYPTION ---

    # the key should be random binary, use scrypt, bcrypt or PBKDF2 to
    # convert a string into a key
    # key is specified using hexadecimal
    
$key pack('H*'"bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
    
    
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
    # and 256 respectively
    
$key_size =  strlen($key);
    echo 
"Key size: " $key_size "\n";
    
    
$plaintext "This string was AES-256 / CBC / ZeroBytePadding encrypted.";

    
# create a random IV to use with CBC encoding
    
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC);
    
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
    
    
# use an explicit encoding for the plain text
    
$plaintext_utf8 utf8_encode($plaintext);
    
    
# creates a cipher text compatible with AES (Rijndael block size = 128)
    # to keep the text confidential 
    # only suitable for encoded input that never ends with value 00h
    # (because of default zero padding)
    
$ciphertext mcrypt_encrypt(MCRYPT_RIJNDAEL_128$key,
                                 
$plaintext_utf8MCRYPT_MODE_CBC$iv);

    
# prepend the IV for it to be available for decryption
    
$ciphertext $iv $ciphertext;
    
    
# encode the resulting cipher text so it can be represented by a string
    
$ciphertext_base64 base64_encode($ciphertext);

    echo  
$ciphertext_base64 "\n";

    
# === WARNING ===

    # Resulting cipher text has no integrity or authenticity added
    # and is not protected against padding oracle attacks.
    
    # --- DECRYPTION ---
    
    
$ciphertext_dec base64_decode($ciphertext_base64);
    
    
# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
    
$iv_dec substr($ciphertext_dec0$iv_size);
    
    
# retrieves the cipher text (everything except the $iv_size in the front)
    
$ciphertext_dec substr($ciphertext_dec$iv_size);

    
# may remove 00h valued characters from end of plain text
    
$plaintext_utf8_dec mcrypt_decrypt(MCRYPT_RIJNDAEL_128$key,
                                         
$ciphertext_decMCRYPT_MODE_CBC$iv_dec);
    
    echo  
$plaintext_utf8_dec "\n";
?>

以上例程会输出:

Key size: 32
ENJW8mS2KaJoNB5E5CoSAAu0xARgsR1bdzFWpEn+poYw45q+73az5kYi4j+0haevext1dGrcW8Qi59txfCBV8BBj3bzRP3dFCp3CPQSJ8eU=
This string was AES-256 / CBC / ZeroBytePadding encrypted.

See also mcrypt_module_open() for a more advanced API and an example.


Mcrypt 函数
在线手册:中文  英文

用户评论:

MadMass (2013-03-19 21:42:48)

Note that the IV must be the same for mcrypt_encrypt and mcrypt_decrypt, otherwise you will have corrupted data after decryption.

Scott.a.Herbert at googlemail.com (2012-10-06 21:49:40)

It is always better to use a standard encryption cipher's rather than to "roll your own", firstly the standard cipher has been tested by world class crypto-analysis's where as unless your a world class crypto-analysis (and if you are why are you even thinking of rolling your own?!?) you won't have the skills needed to even test it (for example if you just XOR each character with a key, it may look secure (the text will be different) but if you count the number of times a character is repeated you see whatever the letter "E" encrypts to occurs more often then the encrypted "Z" (assuming English language plain text)
Secondly, you may think that the hidden nature of your cipher makes it more secure, but the fact is that your cipher is likely *only* secure because it's secret, if someone what able to break-in to your site and steal your code (but not your key) they maybe able break you encrypted data, if someone broke in and found you where using Blowfish (for example) it wouldn't help them.

p dot ranjitsingh at yahoo dot com (2012-06-25 04:54:58)

we can also create encrypt and decrypt function to make our data secure.

This is a simple example to make you understand that how we can make own encryption and decryption.
<?php
class Cipher
{
    function 
encrypt($plain)
    {
        
$length=strlen($plain);
        for(
$i=0;$i<$length;$i++)
        {
            
$temp[$i]=chr(ord($plain[$i])+$i*5);
        }    
        
$cipher=implode($temp);
        return 
$cipher;
    }
    function 
decrypt($cipher)
    {    
        
$length=strlen($cipher);
        for(
$i=0;$i<$length;$i++)
        {
            
$temp[$i]=chr(ord($cipher[$i])-$i*5);
        }
        
$plain=implode($temp);        
        return 
$plain;
    }
}
?>
but we should note that when we create own encryption and decryption function then strength of encryption depends on our logic that make data encrypted.
so make it powerful as you can.

Above example is a basic example and easy to understand by a professional hacker or a good programmer.

antonio dot daeliminare dot bonifati at gmail dot com (2011-08-01 05:57:05)

If you want to be interoperable with other PKCS #7 padding implementations, like the Legion of the Bouncy Castle Java cryptography APIs, you should always pad, that is a 8-byte (block size) padding should be added, even if not necessary:

<?php

function encrypt($str$key)
{
    
$block mcrypt_get_block_size('des''ecb');
    
$pad $block - (strlen($str) % $block);
    
$str .= str_repeat(chr($pad), $pad);

    return 
mcrypt_encrypt(MCRYPT_DES$key$strMCRYPT_MODE_ECB);
}

function 
decrypt($str$key)
{   
    
$str mcrypt_decrypt(MCRYPT_DES$key$strMCRYPT_MODE_ECB);

    
$block mcrypt_get_block_size('des''ecb');
    
$pad ord($str[($len strlen($str)) - 1]);
    return 
substr($str0strlen($str) - $pad);
}

?>

antonio dot daeliminare dot bonifati at gmail dot com (2011-08-01 03:24:02)

Simple DES-ECB binary string encryption/decryption (no initialization vector). I implement PKCS7-padding the right way. This is better than Mcrypt default zero-padding.

<?php

function encrypt($str$key)
{
    
# Add PKCS7 padding.
    
$block mcrypt_get_block_size('des''ecb');
    if ((
$pad $block - (strlen($str) % $block)) < $block) {
      
$str .= str_repeat(chr($pad), $pad);
    }

    return 
mcrypt_encrypt(MCRYPT_DES$key$strMCRYPT_MODE_ECB);
}

function 
decrypt($str$key)
{
    
$str mcrypt_decrypt(MCRYPT_DES$key$strMCRYPT_MODE_ECB);

    
# Strip padding out.
    
$block mcrypt_get_block_size('des''ecb');
    
$pad ord($str[($len strlen($str)) - 1]);
    if (
$pad && $pad $block && preg_match(
          
'/' chr($pad) . '{' $pad '}$/'$str
                                            
)
       ) {
      return 
substr($str0strlen($str) - $pad);
    }
    return 
$str;
}
?>

I am using these functions to encrypt query strings:

<?php
const KEY "\xc8\xd9\xb9\x06\xd9\xe8\xc9\xd2"# Change this

# Send encrypted GET query string
$query encrypt('field1=value1&field2=value2'KEY);
echo 
'<a href="script.php?' urlencode($query) . '">link</a>';

# Receive encrypted GET query string
$query decrypt(urldecode($_SERVER['QUERY_STRING']), KEY);
parse_str($query$query);
$query filter_var_array($query, array(...));

?>

Anonymous (2011-05-12 19:03:54)

In the other notes there are some misconceptions about crypto and the IV, especially for CBC mode.

The most important point: Encryption DOES NOT provide any proof of data integrity or authentication WHATSOEVER. If you need to be sure that the data is secret and not tampered with, you need to encrypt THEN use a keyed HMAC.

For CBC mode, the IV DOES NOT need to be secret. It can be sent along with the plaintext. It needs to be UNIQUE and RANDOM. So that every message is encrypted with a different IV.

The best way to generate an IV is to use mcrypt_create_iv().

Keys must be binary, not ASCII. To create a key from a password:

<?php
$password 
"MyPassword!1!";
$aes256Key hash("SHA256"$passwordtrue); //we want a 32 byte binary blob
?>

das700 at gmail dot com (2011-02-13 19:58:47)

For anyone that wants PKCS7 compatibility (since PHP default is to use Zeros padding) I've found this to work rather well (and seems binary compatible)
<?php
header
("Content-type: text/plain");
function 
addpadding($string$blocksize 32){
    
$len strlen($string);
    
$pad $blocksize - ($len $blocksize);
    
$string .= str_repeat(chr($pad), $pad);
    return 
$string;
}
function 
strippadding($string){
    
$slast ord(substr($string, -1));
    
$slastc chr($slast);
    
$pcheck substr($string, -$slast);
    if(
preg_match("/$slastc{".$slast."}/"$string)){
        
$string substr($string0strlen($string)-$slast);
        return 
$string;
    } else {
        return 
false;
    }
}
function 
keytest($keyfile "key.key"){
    
$keyfile file($keyfile);
    
$key base64_decode($keyfile[0]);
    
$iv base64_decode($keyfile[1]);
    
$enc mcrypt_encrypt(MCRYPT_RIJNDAEL_256$keyaddpadding("Hello World"), MCRYPT_MODE_CBC$iv);
    
$dec strippadding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256$key$encMCRYPT_MODE_CBC$iv));
    echo 
"Encrypted:".base64_encode($enc)."\n";
    echo 
"Decrypted:$dec";
}
keytest();
?>

The key.key file basically just looks like this

jZjneNba78tqCuB8l8eQrXo4nCs6LmlRMflfjEdnnLg=
Uty9weAigmbjIwwng3532FJbeXxGJzhl4Ymw9ry6Slc=

And from this it is entirely compatible with C#'s PaddingMode.PKCS7 which I needed for an application I wrote, I hope this helps!

Anonymous (2011-01-16 11:40:44)

I've noticed some people using a-z, A-Z and 0-9 for keys and stating things like "16 characters is a 128-bit key". This isn't true. Using only these characters, you will get at most 6 bits of entropy per chartacter:
log2(26 + 26 + 10) = 5.954196310386876
So you're actually only getting 95 bits of entropy in 16 characters, which is 0.0000000117% of the keyspace you would get if you were using the full range.
In order to get the full entropy from a key using just a-z, A-Z and 0-9 you should multiply your key length by 1.3333 to account for the 2 bits of lost entropy per byte.

Robin Leffmann (2010-03-09 05:58:13)

Contrary to what is implied in the mcrypt_encrypt() manual page, as well as the info given regarding the CBC vs CFB modes, mcrypt_encrypt() works just fine for encrypting binary data as well.
 
A simple example verifies that the decrypted output is binary identical once cut to its original length:
 
<?php

// 448-bit key (56 bytes) - the only size that mcrypt/php uses for the Blowfish cipher
// (using a smaller key works just fine, as mcrypt appends \0 to reach proper key-size)
$key 'SADFo92jzVnzSj39IUYGvi6eL8v6RvJH8Cytuiouh547vCytdyUFl76R';

// Blowfish/CBC uses an 8-byte IV
$iv substrmd5(mt_rand(),true), 0);

// do 50 encrypt/decrypt operations on some random data, and verify integrity with md5()
for( $i 0$i 50$i++ )
{
    
// create a random, binary string of random length
    
$size mt_rand25000500000 );
    
$c 0$data null;
    while( 
$c++ * 16 $size )
        
$data .= md5mt_rand(), true );
    
$data substr$data0$size );
    
$cksum md5$data );

    
// encrypt using Blowfish/CBC
    
$enc mcrypt_encryptMCRYPT_BLOWFISH$key$dataMCRYPT_MODE_CBC$iv );

    echo 
$size ' -> ' strlen$enc ) . ' -> ';

    
// decrypt (using same IV - a must for the CBC mode)
    
$dec mcrypt_decryptMCRYPT_BLOWFISH$key$encMCRYPT_MODE_CBC$iv );

    
// cut the output with substr(), NOT by using rtrim() as is suggested in some of
    // the mcrypt manual pages - this is binary data, not plaintext
    
echo ( md5(substr($dec0$size)) == $cksum 'ok' 'bad' ) . PHP_EOL;
}

?>

jamesthome at yahoo dot com (2010-02-22 10:05:15)

If you are encrypting a password and saving it into a MySQL blob field, be aware that MySQL will trim the encoded password while doing the insert. If your encoded password has a trailing space, it will be removed on insert and decrypt will not work correctly. However you use the encrypt function, make sure your encrypted password does not have a trailing space.

MiroBasha (2010-02-13 21:04:58)

For anyone using bouncycastle lite (J2ME), don't forget to use "ZeroBytePadding".
I.e,
cipher = new PaddedBufferedBlockCipher (new CBCBlockCipher(new BlowfishEngine()), new ZeroBytePadding());

Roman Solomatin (2010-02-12 08:58:39)

Keep in mind, that when you use MCRYPT_MODE_CBC then the key and IV must be the same when encrypting and decrypting data. Randomising IV does not work with MCRYPT_MODE_CBC.

Jon (2009-05-28 23:42:29)

ECB mode has weaknesses. Use CBC mode instead.

Kai Sellgren (2009-03-13 03:03:03)

There are a couple of things to remember when encrypting data.
1) For CBC, the IV must be random, but not unique. It also must not be known.
2) For CTR, the IV must be unique and not known, but does not need to be random.
3) The key of the encryption is really important.
4) The random used in the previous example of mine is not that great. The post was a response to earlier post saying "for those that just want some simple encryption/decryption". Use better random functions. MCRYPT_RAND just uses the built-in linear congruential generator, which is poor.
5) You may consider using RIJNDAEL-512 or even -1024.
6) If you want to be able to have NULL bytes in your plaintext, then you should store the plaintext length within the encrypted text to strip out padded NULL bytes.

bantam at banime dot com (2008-12-08 21:06:44)

There's a lot of old information on this page, for those that just want some simple encryption/decryption try this out.

<?php
    define
('SALT''whateveryouwant');
    
    function 
encrypt($text)
    {
        return 
trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256SALT$textMCRYPT_MODE_ECBmcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256MCRYPT_MODE_ECB), MCRYPT_RAND))));
    }

    function 
decrypt($text)
    {
        return 
trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256SALTbase64_decode($text), MCRYPT_MODE_ECBmcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256MCRYPT_MODE_ECB), MCRYPT_RAND)));
    }
?>

then try out something like:

<?php
$encryptedmessage 
encrypt("You're my only hope!");
echo 
decrypt($encryptedmessage);
?>

It should return your original message. You can remove the base64_encode and base64_decode from the functions if you want to save space on the encoded string, I use it to simplify database storage.

Anonymous (2007-10-16 16:15:24)

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()...

dylan at wedefy dot com (2007-10-16 08:27:50)

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$inputMCRYPT_MODE_ECB$this->iv));
    }
    function 
decrypt($input) {
        return 
trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256$this->securekeybase64_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);
?>

davidwhthomas at gmail (2006-11-30 18:52:35)

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.

davidwhthomas at gmail (2006-11-29 12:41:28)

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_256MCRYPT_MODE_ECB);
   
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
   
$crypttext mcrypt_encrypt(MCRYPT_RIJNDAEL_256$key$textMCRYPT_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_256MCRYPT_MODE_ECB);
   
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
   
$decrypttext mcrypt_decrypt(MCRYPT_RIJNDAEL_256$key$crypttextMCRYPT_MODE_ECB$iv);
   return 
trim($decrypttext);
}

?>

d a v i d w h t h o m a s @ g m a i l (2006-11-27 17:37:52)

Here's two simple functions to encrypt and decrypt a string:

<?php
function encryptData($value){
   
$key "top secret key";
   
$text $value;
   
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256MCRYPT_MODE_ECB);
   
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
   
$crypttext mcrypt_encrypt(MCRYPT_RIJNDAEL_256$key$textMCRYPT_MODE_ECB$iv);
   return 
$crypttext;
}

function 
decryptData($value){
   
$key "top secret key";
   
$crypttext $value;
   
$iv_size mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256MCRYPT_MODE_ECB);
   
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
   
$decrypttext mcrypt_decrypt(MCRYPT_RIJNDAEL_256$key$crypttextMCRYPT_MODE_ECB$iv);
   return 
trim($decrypttext);
}
?>

stonecypher at gmail dot com (2006-09-11 13:11:34)

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 at yahoo dot com (2006-07-24 14:35:45)

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

alexandrub83 at yahoo dot com (2005-09-24 18:53:50)

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

jesse at pctest dot com (2004-12-07 14:43:11)

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$dataMCRYPT_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 at nflc dot org (2004-12-03 14:04:36)

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:

<?php
$key_hex 
'66e94bd4ef8a2c3b884cfa59ca342b2e';
$key_bin pack('H*'$key_hex);
$pt mcrypt_decrypt(MCRYPT_RIJNDAEL_128$key_bin$etMCRYPT_MODE_ECB);
?>

chris at TRIMTHIS dot chriscodes dot com (2004-08-14 07:31:42)

[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($tdMCRYPT_MODE_ECB); // Dependant on cipher/mode combination (http://www.php.net/manual/en/function.mcrypt-get-iv-size.php)
$iv mcrypt_create_iv($iv_sizeMCRYPT_RAND); // Creates an IV (http://www.ciphersbyritter.com/glossary.htm#IV)

echo "Original data: $data<br />";

$encrypted_data mcrypt_encrypt($td$key$dataMCRYPT_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_dataMCRYPT_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!

易百教程