在这篇教程中你将学到如何使用PHP自带的Mcrypt函数进行加密和解密。Mcypt 库 (http://mcrypt.sourceforge.net/), 让加密/解密变的非常容易。 Mcrypt 支持非常多的加密算法,一定能够满足你的需求. 在教程中,我可能不会涉及所有Mcrypt支持的算法和模块,但是我会提供一个简单的加密接口一边从php访问。虽然mcrypt提供了相当好用的加密方式,但没有任何加密时牢不可破的,因此你把加密过的信息保存在数据库或其他类似的足够安全的地方。
教程需求:
+ 任何安装有PHP 4.x 或者 PHP 5.x的web服务器
+ 编译进php的Mcrypt模块或者作为一个共享模块存在(需要 libmcrypt)
为什么我们使用Mcrypt?
和hash算法相比, 比如: md5, sha1, 或其他加密算法,他们只允许信息加密后以便以后验证比较使用, Mcrypt 允许人们轻松地加密并且解密信息, mcrypt 提供的两种加密方式有着非常广泛的应用,包括但不限于:
+ 安全储存机密信息 (ie: 密码, 信用卡号码, 身份证号码, etc)
+ 安全的信息验证 (ie: email, 服务器与服务器通信, 应用和应用间的通信, etc)
+ 安全储存文件 (ie: 私钥, 安全证书, etc )
mcrypt 同样提供了丰富的加密模式:
+ ECB (electronic codebook) 适用于较小量的数据,如积分值等。
+ CBC (cipher block chaining) 适用于加密大量的数据,如文件。
+ CFB (cipher feedback) 适用于数据量非常小的加密,其中每个字节都会被加密,安全程度高
根据你安装的 libmcrypt/mcrypt 的版本, mcrypt 支持很多种加密算法:
3DES
ARCFOUR_IV (libmcrypt > 2.4.x only)
ARCFOUR (libmcrypt > 2.4.x only)
BLOWFISH
CAST_128
CAST_256
CRYPT
DES
DES_COMPAT (libmcrypt 2.2.x only)
ENIGMA (libmcrypt > 2.4.x only, alias for CRYPT)
GOST
IDEA (non-free)
LOKI97 (libmcrypt > 2.4.x only)
MARS (libmcrypt > 2.4.x only, non-free)
PANAMA (libmcrypt > 2.4.x only)
RIJNDAEL_128 (libmcrypt > 2.4.x only)
RIJNDAEL_192 (libmcrypt > 2.4.x only)
RIJNDAEL_256 (libmcrypt > 2.4.x only)
RC2
RC4 (libmcrypt 2.2.x only)
RC6 (libmcrypt > 2.4.x only)
RC6_128 (libmcrypt 2.2.x only)
RC6_192 (libmcrypt 2.2.x only)
RC6_256 (libmcrypt 2.2.x only)
SAFER64
SAFER128
SAFERPLUS (libmcrypt > 2.4.x only)
SERPENT(libmcrypt > 2.4.x only)
SERPENT_128 (libmcrypt 2.2.x only)
SERPENT_192 (libmcrypt 2.2.x only)
SERPENT_256 (libmcrypt 2.2.x only)
SKIPJACK (libmcrypt > 2.4.x only)
TEAN (libmcrypt 2.2.x only)
THREEWAY
TRIPLEDES (libmcrypt > 2.4.x only)
TWOFISH (for older mcrypt 2.x versions, or mcrypt > 2.4.x )
TWOFISH128 (TWOFISHxxx are available in newer 2.x versions, but not in the 2.4.x versions)
TWOFISH192
TWOFISH256
WAKE (libmcrypt > 2.4.x only)
XTEA (libmcrypt > 2.4.x only)
最后推荐一个Mcrypt的加密类,phpFreaksCrypto Class (PHP4)
这个类会帮你完成绝大部分加密解密的工作,你只需要掌握一些最基本的使用方法即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php /* * phpFreaksCrypto.class.php4 -> phpFreaksCrypto Class (PHP4) */ /** * @author Dustin Whittle * @version 0.01 */ if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) { // tell people trying to access this file directly goodbye... exit('This file can not be accessed directly...'); } class phpFreaksCrypto { var $td; // this gets called when class is instantiated function phpFreaksCrypto($key = 'MyRandomStringThatWillAlwaysBeTheSame', $iv = false, $algorithm = 'tripledes', $mode = 'ecb') { if(extension_loaded('mcrypt') === FALSE) { $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; dl($prefix . 'mcrypt.' . PHP_SHLIB_SUFFIX) or die('The Mcrypt module could not be loaded.'); } if($mode != 'ecb' && $iv === false) { /* the iv must remain the same from encryption to decryption and is usually passed into the encrypted string in some form, but not always. */ die('In order to use encryption modes other then ecb, you must specify a unique and consistent initialization vector.'); } // set mcrypt mode and cipher $this->td = mcrypt_module_open($algorithm, '', $mode, '') ; // Unix has better pseudo random number generator then mcrypt, so if it is available lets use it! $random_seed = strstr(PHP_OS, "WIN") ? MCRYPT_RAND : MCRYPT_DEV_RANDOM; // if initialization vector set in constructor use it else, generate from random seed $iv = ($iv === false) ? mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), $random_seed) : substr($iv, 0, mcrypt_enc_get_iv_size($this->td)); // get the expected key size based on mode and cipher $expected_key_size = mcrypt_enc_get_key_size($this->td); // we dont need to know the real key, we just need to be able to confirm a hashed version $key = substr(md5($key), 0, $expected_key_size); // initialize mcrypt library with mode/cipher, encryption key, and random initialization vector mcrypt_generic_init($this->td, $key, $iv); } function encrypt($plain_string) { /* encrypt string using mcrypt and then encode any special characters and then return the encrypted string */ return base64_encode(mcrypt_generic($this->td, $plain_string)); } function decrypt($encrypted_string) { /* remove any special characters then decrypt string using mcrypt and then trim null padding and then finally return the encrypted string */ return trim(mdecrypt_generic($this->td, base64_decode($encrypted_string))); } // since php 4 does not have deconstructors, we will need to manually call this function function __destruct() { // shutdown mcrypt mcrypt_generic_deinit($this->td); // close mcrypt cipher module mcrypt_module_close($this->td); } } ?> |
一个简单的示例 (PHP4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php require_once('phpFreaksCrypto.class.php4'); // require the phpFreaksCrypto class $crypto = new phpFreaksCrypto(); $the_string_to_be_encrypted = 'blah.blah.blah'; $the_string_that_is_encrypted = $crypto->encrypt($the_string_to_be_encrypted); $the_encrypted_string_decrypted = $crypto->decrypt($the_string_that_is_encrypted); $crypto->__destruct(); echo 'Original: ' . $the_string_to_be_encrypted . '<br />'; echo 'Encrypted: ' . $the_string_that_is_encrypted . '<br />'; echo 'Decrypted: ' . $the_encrypted_string_decrypted . '<br />'; ?> |
适用于PHP5的 phpFreaksCrypto Class (PHP5)
这两个类只是有些语法上的差别,引入了PHP5的一些新的特性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | <?php /* * phpFreaksCrypto.class.php5 -> phpFreaksCrypto Class (PHP5) */ /** * @author Dustin Whittle * @version 0.01 */ if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) { // tell people trying to access this file directly goodbye... exit('This file can not be accessed directly...'); } class phpFreaksCrypto { private $td; // this gets called when class is instantiated public function __construct($key = 'MyRandomStringThatWillAlwaysBeTheSame', $iv = false, $algorithm = 'tripledes', $mode = 'ecb') { if(extension_loaded('mcrypt') === FALSE) { $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; dl($prefix . 'mcrypt.' . PHP_SHLIB_SUFFIX) or die('The Mcrypt module could not be loaded.'); } if($mode != 'ecb' && $iv === false) { /* the iv must remain the same from encryption to decryption and is usually passed into the encrypted string in some form, but not always. */ die('In order to use encryption modes other then ecb, you must specify a unique and consistent initialization vector.'); } // set mcrypt mode and cipher $this->td = mcrypt_module_open($algorithm, '', $mode, '') ; // Unix has better pseudo random number generator then mcrypt, so if it is available lets use it! $random_seed = strstr(PHP_OS, "WIN") ? MCRYPT_RAND : MCRYPT_DEV_RANDOM; // if initialization vector set in constructor use it else, generate from random seed $iv = ($iv === false) ? mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), $random_seed) : substr($iv, 0, mcrypt_enc_get_iv_size($this->td)); // get the expected key size based on mode and cipher $expected_key_size = mcrypt_enc_get_key_size($this->td); // we dont need to know the real key, we just need to be able to confirm a hashed version $key = substr(md5($key), 0, $expected_key_size); // initialize mcrypt library with mode/cipher, encryption key, and random initialization vector mcrypt_generic_init($this->td, $key, $iv); } public function encrypt($plain_string) { /* encrypt string using mcrypt and then encode any special characters and then return the encrypted string */ return base64_encode(mcrypt_generic($this->td, $plain_string)); } public function decrypt($encrypted_string) { /* remove any special characters then decrypt string using mcrypt and then trim null padding and then finally return the encrypted string */ return trim(mdecrypt_generic($this->td, base64_decode($encrypted_string))); } // this function gets called when php garbage collection destroys the object public function __destruct() { // shutdown mcrypt mcrypt_generic_deinit($this->td); // close mcrypt cipher module mcrypt_module_close($this->td); } } ?> |
使用示例(PHP5)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php require_once('phpFreaksCrypto.class.php5'); // require the phpFreaksCrypto class $crypto = new phpFreaksCrypto(); $the_string_to_be_encrypted = 'blah.blah.blah'; $the_string_that_is_encrypted = $crypto->encrypt($the_string_to_be_encrypted); $the_encrypted_string_decrypted = $crypto->decrypt($the_string_that_is_encrypted); echo 'Original: ' . $the_string_to_be_encrypted . '<br />'; echo 'Encrypted: ' . $the_string_that_is_encrypted . '<br />'; echo 'Decrypted: ' . $the_encrypted_string_decrypted . '<br />'; ?> |
另外在Codeigniter上也有一个实现了mcrypt的库,也可以考虑把那个类移植过来使用
博主,能否帮我下.我编译安装mcrypt无法通过.
[回复]
这个模板很简洁~
第一次来这~
[回复]
博主的代码框是怎么弄的?
[回复]
南柯一梦 回复:
五月 24th, 2010 at 11:23 下午
是WordPress里的一个插件,名字貌似是codebox
[回复]