[转载]PHP对称加密

本文转自Laravel技术社区,仅限个人学习收藏。

对称加密算法是指,数据发信方将明文(原始数据)和密钥一起经过加密处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若要解读原文,则需要使用加密密钥及相同算法的逆算法对密文进行解密,使其恢复成可读明文。对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高,适用于加密大量数据的场合。常用的算法有DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。

PHP中如果需要使用对称加密算法,则需要mcrypt扩展的支持。PHP的mcrypt扩展提供了强大的加密解密方法,支持19种加密算法和8种加密模式,具体可以通过函数mcrypt_list_algorithms()和mcrypt_list_modes()来显示。

  1. <?php
  2. $type_list = mcrypt_list_algorithms();  //mcrypt支持的加密算法列表
  3. $mode_list = mcrypt_list_modes();  //mcrypt支持的加密模式列表
  4. print_r($type_list);
  5. print_r($mode_list);
  6. ?>

使用DES方式加密的代码如下。

  1. <?php
  2. $auth_key = 'safe_key';
  3. $salt = '!@#$%';
  4. $content = 'Hello World';
  5. $td = mcrypt_module_open(mcrypt_des,'','ecb','');  //使用mcrypt_des算法ecb模式
  6. $iv_size = mcrypt_enc_get_iv_size($td);  //设置初始向量大小
  7. $iv = mcrypt_create_iv($iv_size,mcrypt_rand);  //创建初始向量
  8. $key_size = mcrypt_enc_get_key_size($td);  //返回所支持的最大密钥长度(以字节计算)
  9. $key = substr(md5($auth_key.salt),0,$key_size);
  10. mcrypt_generic_init($td$key$iv);  //初始化
  11. $secret = mcrypt_generic($td$content);  //加密并返回加密后的内容
  12. echo base64_encode($secret);
  13. mcrypt_generic_deinit($td);
  14. mcrypt_module_close($td);  //结束
  15. ?>

使用DES方式解密的代码如下。

  1. <?php
  2. $auth_key = 'safe_key';
  3. $salt = '!@#$%';
  4. $secret = 'nzPa0jPaaNca+Yty/HG4PA==';
  5. $td = mcrypt_module_open(mcrypt_des,'','ecb','');  //使用mcrypt_des算法ecb模式
  6. $iv_size = mcrypt_enc_get_iv_size($td);  //设置初始向量大小
  7. $iv = mcrypt_create_iv($iv_size,mcrypt_rand);  //创建初始向量
  8. $key_size = mcrypt_enc_get_key_size($td);  //返回所支持的最大密钥长度(以字节计算)
  9. $key = substr(md5($auth_key.salt),0,$key_size);
  10. mcrypt_generic_init($td$key$iv);  //初始化
  11. $content = mdecrypt_generic($tdbase64_decode($secret));  //解密并返回内容
  12. echo $content;
  13. mcrypt_generic_deinit($td);
  14. mcrypt_module_close($td);  //结束
  15. ?>

AES是Advanced Encryption Standard(高级加密标准)的缩写,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(National Institute of Standards and Technology,NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。至2006年,高级加密标准已经成为对称密钥加密中最流行的算法之一。

AES目前有五种加密模式。

(1)电码本(Electronic Codebook,ECB)模式。

(2)密码分组链接(Cipher Block Chaining,CBC)模式。

(3)计数(Counter,CTR)模式。

(4)密码反馈(Cipher FeedBack,CFB)模式。

(5)输出反馈(Output FeedBack,OFB)模式。

在PHP的mcrypt扩展中,rijndael-128、rijndael-192、rijndael-256就是AES加密,三种分别使用不同的数据块和密钥长度进行加密。

在AES的ECB模式中,一般是16字节为一块,然后对这一整块进行加密,如果输入的字符串不够16字节,就需要补位。

使用AES-ECB方式进行加密数据的代码如下。

  1. <?php
  2. $auth_key = 'safe_key';
  3. $salt = '!@#$%';
  4. $content = 'Hello World';
  5. $td= mcrypt_module_open(mcrypt_rijndael_128,'',mcrypt_mode_ecb,'');
  6. $iv_size = mcrypt_enc_get_iv_size($td);
  7. $iv = mcrypt_create_iv($iv_size,mcrypt_rand);
  8. $key_size = mcrypt_enc_get_key_size($td);
  9. $key = substr(md5($auth_key.salt),0,$key_size);
  10. mcrypt_generic_init($td$key$iv);
  11. $block=mcrypt_get_block_size(mcrypt_rijndael_128,mcrypt_mode_ecb);
  12. $pad=$block-(strlen($content) % $block);
  13. $content.=str_repeat(chr($pad),$pad); // 补齐不足16字符的位数内容
  14. $secret = mcrypt_generic($td$content);
  15. echo bin2hex($secret);
  16. mcrypt_generic_deinit($td);
  17. mcrypt_module_close($td);
  18. ?>

使用AES-ECB方式进行解密数据如下。

  1. <?php
  2. $auth_key = 'safe_key';
  3. $salt = '!@#$%';
  4. $secret = 'd62d9e7e8ad4b0f044e4bd971f695a58';
  5. $td= mcrypt_module_open(mcrypt_rijndael_128,'',mcrypt_mode_ecb,'');
  6. $iv_size = mcrypt_enc_get_iv_size($td);
  7. $iv = mcrypt_create_iv($iv_size,mcrypt_rand);
  8. $key_size = mcrypt_enc_get_key_size($td);
  9. $key = substr(md5($auth_key.salt),0,$key_size);
  10. mcrypt_generic_init($td$key$iv);
  11. $content=mdecrypt_generic($td,hex2bin($secret));
  12. $len=strlen($content);
  13. $ch=ord($content[$len-1]);
  14. echo substr($content,0,$len-$ch);
  15. mcrypt_generic_deinit($td);
  16. mcrypt_module_close($td);
  17. ?>

AES的CBC加密模式,需要添加初始化向量(IV),默认是16个0。由于是分组加密,因此下一组的IV就用前一组的加密的密文来充当。CFB、OFB模式类似,只不过更复杂,从而破解难度更大。

使用AES-CBC方式进行加密解密数据的代码如下。

  1. <?php
  2. $auth_key = 'safe_key';
  3. $salt = '!@#$%';
  4. $content = 'Hello World';
  5. $td= mcrypt_module_open(mcrypt_rijndael_128,'',mcrypt_mode_cbc,'');
  6. $iv_size = mcrypt_enc_get_iv_size($td);
  7. $iv = mcrypt_create_iv($iv_size,mcrypt_rand);
  8. $key_size = mcrypt_enc_get_key_size($td);
  9. $key = substr(md5($auth_key.salt),0,$key_size);
  10. mcrypt_generic_init($td$key$iv);
  11. $secret = mcrypt_generic($td$content); // 加密数据
  12. echo bin2hex($secret);
  13. mcrypt_generic_deinit($td);
  14. mcrypt_module_close($td);
  15. $td= mcrypt_module_open(mcrypt_rijndael_128,'',mcrypt_mode_cbc,'');
  16. mcrypt_generic_init($td$key$iv);
  17. echo mdecrypt_generic($td,$secret); // 解密数据
  18. mcrypt_generic_deinit($td);
  19. mcrypt_module_close($td);
  20. ?>

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!