转自:http://www.smatrix.org/bbs/simple/index.php?t5662.html

//
目录
1.    PHP的散列函数及其应用
2.    PHP中的对称密码算法及其应用
3.    PHP的公钥密码算法及其应用
///

2 PHP中的对称密码算法及其应用
前一段时间一直想写完PHP中的密码学算法及其应用的三大部分,但无奈琐事繁多,所以一直拖到现在,希望能够以通俗而非学术化的语言说清楚这部分。
2.1 什么是对称密码算法
   前面我们将的HASH函数并非真正的密码算法,而只是一个生成消息摘要的函数。因为一个密码系统需要有五个要素部分组成(密文,明文,加密算法,解密算 法,密钥)。区别对称与非对称密码算法的关键在于解密密钥是否会等于加密密钥,如果相等,那么就是对称的,不相等就是非对称的。像DES,AES都属于对 称密码算法,而RSA,ECC都属于非对称的公钥密码算法。一般而言,对称密码算法加解密速度较快,通常是用来进行数据加密,而非对称的公钥加密算法加解 密速度较慢,通常是用来进行数字签名和构造复杂的密码协议。坊间传说的某某公钥加密算法比某某对称加密算法更好更安全实属荒谬,这就好比讨论你的手和脚那 个更有用。
2.2 什么叫做对称密码算法的加密模式
这个是很多开发人员搞得不太清楚的东西,毕竟大部分PHP开发者未必都接触过密码学方 面的专业培训,因此看到PHP的相关函数感觉望而生畏,不知所措。所谓加密模式就是加密任意长度的消息的使用密码算法的方法。通常对称密码算法都会提供至 少四种基本工作模式,其中两组为块模式(ECB和CBC),两组是流模式(CFB和OFB)。打个通俗的比方,密码算法函数就好像个机器,明文就好像原材 料,机器不可能一次处理所有明文,那么块模式的策略就是把明文进行分组,然后按照一定的规则放入机器做处理,然后得到一组密文。ECB模式就是将消息分成 相互独立的块,每一块都用同一算法和密钥加密(比如使用DES),块与块之间没有关联。而CBC也是将消息分成相互独立块,但是加密的时候,做了点手脚, 使得下一块的密文和上一块的密文有关系,分块加密前与上一块的密文进行异或运算,然后在用同一算法和密钥加密,由于第一块明文没有上一块的密文,所以必须 人工指定一个,称之为初始化向量。而CFB和OFB模式把明文看作是二进制流,实际上也是分块的,它们都需要一个初始化向量,不断地生成伪随机二进制流, 然后与明文分组进行异或运算,而密文是否参与运算是CFB和OFB之间的区别所在。工作模式详情具体不好用文字描述,有兴趣的不妨密码学方面的书籍(安全 矩阵论坛上很多,随便下一本都有)。
2.3 PHP中的对称密码算法函数
PHP的各个版本都提供了相应的对称密码算法函数,所以PHP的 开发者们完全没必要自己山寨一个,请相信这些提供的对称密码算法函数绝对比你自己设计的更强大。目前为止,不绝于耳的是各种颜色的客(还有祖传的)据说能 够几分钟或者秒破一个密码算法,其实这是误解,除了在看雪论坛上看到几个直接针对密钥的暴力破解实例外,偶在网络上很少见过数学上能攻破一个密码算法的 人。之所以系统或软件被破解,是因为密码算法使用不当或者攻击者绕过了密码算法机制。PHP的主要对称密码算法函数来自于Mcrypt函数族。当然这个函 数族是PHP的可选部件,需要下载libmcrypt-x.x.tar.gz并在PHP.INI中进行配置。你可以通过phpinfo()来看看自己配置 的环境是否支持这些函数。

mcrypt support: enabled
Version:  2.5.8
Api No: 20021217
Supported ciphers:  cast-128 gost rijndael-128 twofish arcfour cast-256 loki97 rijndael-192 saferplus wake blowfish-compat des rijndael-256 serpent xtea blowfish enigma rc2 tripledes
Supported modes:  cbc cfb ctr ecb ncfb nofb ofb stream  

Supported ciphers中列出的就是支持的算法,算法很多,很好很强大,其中rijndael开头的就是AES,所以PHP没有AES实属缪传。接下来我们介绍如 何正确的使用PHP的对称密码算法函数。首先我们看到这个函数mcrypt_module_open,原型是:

resource mcrypt_module_open ( string algorithm, string algorithm_directory, string mode, string mode_directory)

这 个函数的作用实际上是创建一个使用对称加密算法的工作环境(理解这个很重要,如果你学过windows程序设计,这种思想随处可见),告诉PHP要使用何 种算法(第一个参数),算法路径在哪里(第二个参数),采用何种工作模式(第三个参数),工作模式描述的路径在哪里(第四个参数).实际使用中我们一般不 需要设置第二个参数和第四个参数。现在我们看个例子:

<?php$key = "security matrix";  //密钥$input = "mathmatica sounds very terrible!"; //明文//加密$td = mcrypt_module_open('rijndael-256', '', 'cbc', ''); //创建加密环境$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); //由于采用了cbc模式,我们需要一个初始化向量iv。mcrypt_generic_init($td, $key, $iv); //初始化加密算法,当算法模式是ecb时候,会自动忽略iv$encrypted_out_data = mcrypt_generic($td, $input);  //执行加密mcrypt_generic_deinit($td);  //释放加密算法资源      mcrypt_module_close($td);    //关闭加密环境,释放资源echo "明文是:$input";echo '<br>';echo "密钥是:$key";echo '<br>';echo "密文是:$encrypted_out_data";echo '<br>';//解密,由于$iv没有被清掉,所以我们还可以继续用这个。实际使用中一定要保存起来$td = mcrypt_module_open('rijndael-256', '', 'cbc', ''); //创建加密环境mcrypt_generic_init($td, $key, $iv);$decrypted_out_data=mdecrypt_generic($td,  $encrypted_out_data);mcrypt_generic_deinit($td);  //释放加密算法资源      mcrypt_module_close($td);    //关闭加密环境,释放资源echo '<br>';echo "密钥是:$key";echo '<br>';echo "明文是:$decrypted_out_data";

这 段源代码我添加的注释与PHP手册中的说法略有不同,主要是我为了让大家更明白些。这里有几个函数,第一个是mcrypt_create_iv,这个是用 来创建一个随机的初始化向量IV,四种基本模式中,除了ECB,均要有初始化向量IV。mcrypt_generic_init函数用来初始化密码算法对 象,包括具体算法的句柄,密钥和初始化向量。当算法模式是ECB时,该函数会自动忽略初始化向量IV。接下来利用mcrypt_generic执行加密。 加密完成后利用mcrypt_generic_deinit和mcrypt_module_close来释放环境。这个过程和windows程序设计下面 使用设备资源的过程非常相似。值得注意的是,由于IV生成的时候使用了随机数,所以每次是不一样的,也会导致密文不一样。因此除了ECB模式外,其它三种 模式均要把IV记下了,才能进行解密。解密过程和加密过程是一样的,只是函数mcrypt_generic换成了mdecrypt_generic,请注 意,别眼花,注意他们的书写上的区别,前者是加密,后者是解密。这个过程是PHP中标准的使用对称密码算法的过程。
PHP中有些非常陌生的密码算法,比如gost,除非专业搞密码算法的,一般很少人会知道这个算法的具体内容。我们可以使用以下PHP的算法信息函数来了解一个算法:

mcrypt_enc_get_algorithms_name –获取算法具体名称
mcrypt_enc_get_block_size – 获取算法的分组大小
mcrypt_enc_get_iv_size – 获取算法的IV初始化向量大小
mcrypt_enc_get_key_size – 获取算法支持的最大密钥长度
mcrypt_enc_get_modes_name – 获取算法支持的加密模式
mcrypt_enc_get_supported_key_sizes –返回一个数组,里面有算法支持的各种密钥长度 

使用方法如下:

<?php$td = mcrypt_module_open (MCRYPT_BLOWFISH, '', 'ecb', '');echo mcrypt_enc_get_algorithms_name($td). "\n";echo mcrypt_enc_get_block_size($td). "\n";echo mcrypt_enc_get_iv_size($td). "\n";echo mcrypt_enc_get_key_size($td). "\n";echo mcrypt_enc_get_modes_name($td). "\n";//结果:Blowfish 8 8 56 ECB

PHP中除了上述用法之外,还有一种加密解密的用法。依赖于函数mcrypt_encrypt和mcrypt_decrypt,前者用于加密,后者用于解密。其函数原型为:

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

我们很容易发现,两个函数的参数都是完全一样的,实际上也只有一样才能正常的加密和解密。这种用法与前述函数用法的区别在于这两个函数把所有的算法信息当作为自己的参数了,习惯于传统PHP开发的人会觉得这个更加易用。先看个代码:

<?php$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);  //获取该算法在OFB模式下的IV向量大小$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); //创建一个初始化IV向量$key = "security matrix";   //密钥$plaintext = "you should arrive here in eight clock"; //明文$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plaintext, MCRYPT_MODE_CBC, $iv); //直接执行加密echo  "明文是:$plaintext.<br> 密文是: $ciphertext";$outtext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key,$ciphertext, MCRYPT_MODE_CBC, $iv); //执行解密echo "<br>";echo  "解密后的明文是:  $outtext<br>";//结果:// 明文是:you should arrive here in eight clock.//密文是: p 蜉~嵁'mh!Bl廀'Es??{ ?e斤舉* YC¬濤溋C海Rc敻J 偰k躕"蟸v勸//解密后的明文是: you should arrive here in eight clock

除了上面两种全面的用法,PHP还提供了四种直接指定加密模式的加密函数mcrypt_cfb(), mcrypt_cbc(), mcrypt_ecb()和 mcrypt_ofb(),这四个函数的原型几乎是一样的。以mcrypt_cbc()为例,原型如下:

string mcrypt_cbc ( int cipher, string key, string data, int mode [, string iv])
string mcrypt_cbc ( string cipher, string key, string data, int mode [, string iv])

其中第一个参数指定算法,第二个参数指定密钥,第三个参数指定数据(根据后面的mode决定是明文还是密文),第四个参数mode指定是加密操作还是解密操作,第五个参数是可选的,如果需要IV则一定要IV.还是看个例子,你会发现如此简单:

<?php
$key = "security matrix";
$text = "fleshwound is a farmer,deadly wounded ";//明文$ctext = mcrypt_ecb (MCRYPT_3DES, $key, $text, MCRYPT_ENCRYPT); //加密
$ptext = mcrypt_ecb (MCRYPT_3DES, $key, $ctext, MCRYPT_DECRYPT); //解密echo "明文:$text <br> 密文:$ctext <br>解密后明文:$ptext"
//结果:
//明文:fleshwound is a farmer,deadly wounded
//密文:皚剢GsXe?+ ?v?3佉:?缟2 拉哣 磀毄+?
//解密后明文:fleshwound is a farmer,deadly wounded 

好 了,写了几个小时,总算把PHP中对称密码算法介绍完了,其实大家会发现使用还是非常简单的,不会比写一个分页函数难,如果能够在自己项目中得当地使用, 将会使得系统安全性大大提高。而且聪明的童鞋可以从这里找到对PHP源代码自加密自解密的代码生成方法(比ZEND的更具有灵活性),当然也可以用来做坏 事,实现网页级的变形免杀木马,具体方法我不介绍了。下一个专题是PHP中的公钥密码算法,我会尽量将PHP的密码学应用用通俗的方法逐步的引向深入。

转载于:https://www.cnblogs.com/JohnABC/p/3837382.html

PHP-密码学算法及其应用-对称密码算法相关推荐

  1. md5不是对称密码算法_密码学中的消息摘要算法5(MD5)

    md5不是对称密码算法 In cryptography, MD5 (Message-Digest algorithm 5) is a mainly used cryptographic hash fu ...

  2. 密码学:分组密码.(块密码:是一种对称密码算法)

    密码学:分组密码. 分组加密(Block Cipher) 又称为分块加密或块密码,是一种对称密码算法,这类算法将明文分成多个等长的块 (Block) ,使用确定的算法和对称密钥对每组分别加密或解密.分 ...

  3. 密码学学习笔记(二)——对称密码算法(轻量级密码算法Twine)

    文章目录 1. 分组密码(Twine) 1.1 加解密方式 1.1.1 加密 1.1.2 密钥生成算法 1.1.3 解密 1.1.4 全部代码 1.2. 分组密码的模式 1.2.1 ECB模式 1.2 ...

  4. 6 密码学和对称密匙算法

    目录 6.1 密码学的历史里程碑 6.2 密码学的基本知识 6.2.1 密码学的目标 6.2.2 密码学的概念 6.2.3 密码数学 6.2.4 密码 6.3 现代密码学 6.3.1 密码密钥 6.3 ...

  5. 01. 对称密码——算法

    密码算法 DES 首先声明!!! 由于DES的密文可以在短时间内被破译,现已不再使用. 是什么? DES(Data Encryption Standard)是1977年美国联邦信息处理标准(FIPS) ...

  6. 国密学习笔记 对称密码算法

    对称密码的特征是加密密钥和解密密钥完全相同或者一个密钥很容易从另一个密钥中导出. 对称密码有两种主要形式: 序列密码(也叫流密码,stream cipher),国密标准中的ZUC祖冲之算法 ZUC在生 ...

  7. 密码学基础(二)算法和密钥

    区块链兄弟社区,区块链技术专业问答先行者,中国区块链技术爱好者聚集地 作者:于中阳 来源:区块链兄弟 原文链接:http://www.blockchainbrother.com/article/73 ...

  8. 加解密算法及国密算法介绍

    图片内容参看我的网站:www.waltersun.cn 引言 随着信息化的推进,信息安全越来越受到人们的重视.这篇文章简单介绍了常用的密码算法.原理.使用场景,简单比较国密算法,可作为业务使用的入门指 ...

  9. 【密码算法 之十四】非对称算法,ECC椭圆曲线算法 之 ECDSA、ECDH、SM2、SM9等

    文章目录 1. ECC椭圆曲线 1.1 曲线类型 1.2 曲线标准 1.3 表示方法 1.4 曲线运算 1.4.1 点加(Point Addition) 1.4.2 点乘(Point Multipli ...

最新文章

  1. 2020中国人工智能年度评选报名即将截止!4大类别7大奖项开放申请
  2. PHP 开发环境和组织管理
  3. java非法字符65289_求详细点的回答 谢谢
  4. Android加载大图、多图解决方案
  5. POJ 1986 Distance Queries(LCA)
  6. xshell 6 连接debian系统拒绝了密码_Xshell中操作Linux的常用命令,你知道几个?
  7. 第八届育才杯机器人比赛_赛场、名单公布!南海区第八届“献血者杯”羽毛球公开赛“羽”你相约本周六...
  8. Android 通过触摸动态地在屏幕上画矩形
  9. Mastik:微体系结构侧信道攻击工具包
  10. IIS6 JQuery 未定义 解决办法
  11. layui表单基本使用
  12. 服务器安装julia_julia | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror...
  13. linux系统双网卡不能同时启动,针对RHEL中双网卡IP不能同时被访问的解决方法
  14. float数据十六进制表示法,十六进制读取float数据
  15. 07、自己写库—构建库函数雏形
  16. android ibluetootha2dp,无法接收BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED广播
  17. python opencv入门 光流法(41)
  18. 买卖股票的zuija时机含手续费(Java)
  19. 程序员1个经验反复用了10年?工资不涨,那是最终被迫成长的结果
  20. STM32F103RCT6 基于STM32Cube_FW_F1_V1.8.0库建立工程模板

热门文章

  1. 超级账本(Hyperledger Fabric)源码分析之一:总览
  2. 前端分离的前端开发工具_使我成为前端开发人员工作的工具和资源
  3. Tim Berners-Lee重新分散的新Web SOLID简介
  4. 计算机本科学位有用吗_我应该回到学校获得计算机科学学位吗?
  5. Spring Cloud应用开发(四:服务容错保护)
  6. Python培训分享:Python内置标准异常及其解析
  7. 选择PMP培训学校需要注意哪些
  8. String复习笔记
  9. 人人都能学会的python编程教程3:字符串和编码
  10. 排序算法总结之堆排序