当前位置: 首页 > 编程日记 > 正文

PHP-密码学算法及其应用-对称密码算法

转自: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

相关文章:

Swift4 String截取字符串

var str1 "AlexanderYeah";// 1 截取字符串的第一种方式 // prefix 截取前3个字符串 var str2 str1.prefix(3); print(str2);// suffix 截取后3个字符串 var str3 str1.suffix(3); print(str3);// 2 截取一个范围的字符串 // 从0开始 到倒数第二位结束 let idx1 …

angular react_Angular 2 vs React:将会有鲜血

angular reactAngular 2 has reached Beta and appears poised to become the hot new framework of 2016. It’s time for a showdown. Let’s see how it stacks up against 2015’s darling: React.Angular 2已达到Beta版本&#xff0c;并有望成为2016年炙手可热的新框架。该…

Welcome to Swift (苹果官方Swift文档初译与注解三十四)---241~247页(第五章-- 函数)

In-Out Parameters (全局参数) 像前面描述的参数变量,只能在函数体内进行修改,如果你需要函数修改的它的参数值,并且希望这些改变在函数调用结束后仍然有效,可以定义使用全局参数. 定义全局参数使用关键字inout,全局参数的值在函数调用的时候进行传递,在函数体内进行修改,最后函…

递归 尾递归_代码简报:递归,递归,递归

递归 尾递归Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事&#xff1a; A beginner’s guide to recursion: 6 minute read 递归初学者指南&#xff1a; 6分钟阅读 Things you probably didn’t know you …

Hadoop 生态系统

当下 Hadoop 已经成长为一个庞大的生态体系&#xff0c;只要和海量数据相关的领域&#xff0c;都有 Hadoop 的身影。下图是一个 Hadoop 生态系统的图谱&#xff0c;详细列举了在 Hadoop 这个生态系统中出现的各种数据工具。这一切&#xff0c;都起源自 Web 数据爆炸时代的来临。…

socket通信——通过Udp传输方式,将一段文字数据发送出去

需求&#xff1a;通过Udp传输方式&#xff0c;将一段文字数据发送出去定义一个Udp发送端思路&#xff1a;1、建立updsocket服务2、提供数据&#xff0c;并将数据封装到数据包中。3、通过socket服务的发送功能&#xff0c;将数据包发出去4、关闭资源。import java.net.*; class …

编码中统一更该变量的快捷键_流媒体的7种方式使您成为更好的编码器

编码中统一更该变量的快捷键by freeCodeCamp通过freeCodeCamp 流媒体的7种方式使您成为更好的编码器 (7 Ways Streaming Makes you a Better Coder) After coding live on twitch.tv for dozens of hours, I’m convinced that streaming makes you a better coder. Here’s w…

AutoConfig工具使用

下载安装Auto工具包&#xff1a; http://code.taobao.org/mvn/repository/com/alibaba/citrus/tool/antx-autoconfig/1.0.9/antx-autoconfig-1.0.9.tgzhttp://code.taobao.org/mvn/repository/com/alibaba/citrus/tool/antx-autoexpand/1.0.9/antx-autoexpand-1.0.9.tgztar zxv…

Spark2 ML 学习札记

摘要&#xff1a;  1.pipeline 模式 1.1相关概念 1.2代码示例  2.特征提取&#xff0c;转换以及特征选择 2.1特征提取 2.2特征转换 2.3特征选择 3.模型选择与参数选择 3.1 交叉验证 3.2 训练集-测试集 切分 4.spark新增SparkSession与DataSet 内容&#xff1a; 1.pipeline …

xCode 开发快捷键

Ctrl CMD 右箭头返回上一个编辑的界面Ctrl CMD 左箭头返回后一个编辑的界面CMD Option 左箭头区域代码折叠CMD Option 右箭头区域代码展开Shift CMD Option 左箭头折叠界面内所有的代码Shift CMD Option 右箭头展开界面内所有的代码CMD Ctrl 上下箭头.h 和 .m …

javascript模块_JavaScript模块第2部分:模块捆绑

javascript模块by Preethi Kasireddy通过Preethi Kasireddy JavaScript模块第2部分&#xff1a;模块捆绑 (JavaScript Modules Part 2: Module Bundling) In Part I of this post, I talked about what modules are, why developers use them, and the various ways to incorp…

idea上实现github代码同步

1.先将github远程仓库clone到本地 2.将本地仓库中的项目导入到idea中 3.如果你的项目代码不是放在仓库的根目录下&#xff0c;idea会识别到你的项目是在git仓库目录下&#xff0c;必须点击add root才能匹配路径。 4.add root后会发现右击项目时会多了一个git选项 5.在git选项中…

iOS12 UITabbar Item 向上漂移错位的bug

[[UITabBar appearance] setTranslucent:NO]; 加此行代码 完美解决此bug

jQuery学习笔记(一)

补充一些自己容易忘的知识点: event.stopPropagation() 阻止事件冒泡 event.preventDefault() 阻止事件的默认行为 return false 相当于event.stopPropagation() event.preventDefault() 。除了阻止默认行为之外&#xff0c;还会阻止事件冒泡。 转载于:https://www.cnblogs.…

随机网络构建_构建随机报价机

随机网络构建by Ayo Isaiah通过Ayo Isaiah 构建随机报价机 (Building a Random Quote Machine) I really wasn’t entirely satisfied with my first attempt at building a Random Quote Generator on Free Code Camp. It was ugly, and the quotes were too long, so I didn…

20145231 《信息安全系统设计基础》第11周学习总结

20145231《信息安全系统设计基础》第11周学习总结 教材学习内容总结 异常 异常是异常控制流的一种形式&#xff0c;由硬件和操作系统实现。简单来说&#xff0c;就是控制流中的突变。 出现异常的处理方式&#xff1a; 1.处理器检测到有异常发生 2.通过异常表&#xff0c;进行间…

JAR命令使用

jar 命令详解 jar 是随 JDK 安装的&#xff0c;在 JDK 安装目录下的 bin 目录中&#xff0c;Windows 下文件名为 jar.exe&#xff0c;Linux 下文件名为 jar。它的运行需要用到 JDK 安装目录下 lib 目录中的 tools.jar 文件。不过我们除了安装 JDK 什么也不需要做&#xff0c;因…

捍卫者usb管理控制系统_捍卫超模块化JavaScript

捍卫者usb管理控制系统by Mike Groseclose通过Mike Groseclose 捍卫超模块化JavaScript (In Defense of Hyper Modular JavaScript) Last week npmgate was a big topic for the JavaScript community. For those of you who haven’t been following what happened, here’s …

Android开发——布局性能优化的一些技巧(一)

0. 前言上一篇我们分析了为什么LinearLayout会比RelativeLayout性能更高&#xff0c;意义在于分析了这两种布局的实现源码&#xff0c;算是对一个小结论的证明过程&#xff0c;但是对布局性能的优化效果&#xff0c;对这两种布局的选择远不如减少布局层级、避免过分绘制、按需加…

1-RAC基础

1 安装 pod ‘ReactiveObjC’ RAC 其实大大减少了代码量 2 基本使用 // 0 RAC 中最为常见的类 信号类/*RACSignal&#xff1a;信号类1.通过RACSignal 创建1个信号&#xff08;默认&#xff1a;冷信号&#xff09;2.通过订阅者&#xff0c;订阅信号信号&#xff08;变成:热信号…

static用法总结

C的static有两种用法&#xff1a;面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数&#xff0c;不涉及类&#xff1b;后者主要说明static在类中的作用。 一、面向过程设计中的static1、静态全局变量2、静态局部变量3、静态函数二、面向对象的…

小程序 缩放_缩放流星应用程序的初体验

小程序 缩放by Elie Steinbock埃莉斯坦博克(Elie Steinbock) 缩放流星应用程序的初体验 (First Experiences Scaling a Meteor App) I recently went through the challenge and ordeal of having to scale my Meteor app. It’s a project that had already been running in …

SQL Server Lock Escalation - 锁升级

Articles Locking in Microsoft SQL Server (Part 12 – Lock Escalation) http://dba.stackexchange.com/questions/12864/what-is-lock-escalation 2008 R2 Lock Escalation (Database Engine)---Forward from Locking in Microsoft SQL Server (Part 12 – Lock Escalation)…

Jzzhu and Chocolate

CF#257 div2 C:http://codeforces.com/contest/450/problem/C 题意&#xff1a;n*m的方格&#xff0c;每次可以横着或者纵向的切一刀&#xff0c;问切k之后&#xff0c;最小的最大是多少。 题解&#xff1a;比赛的时候没有想到怎么处理&#xff0c;看了别人的题解&#xff0c;才…

2-RACommand

RACommand RACCommand 就是命令 // RACCommand 就是命令// 0 创建一个CMD 穿进去一个用于构建RACSignal的Block参数来初始化RACommandRACCommand *cmd [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {// 此处是cmd 执行的输入源NSLog(…

玻璃上的编码喜悦(+ 10史诗般的Epigrams)

by Den McHenry丹麦克亨利(Den McHenry) 玻璃上的编码喜悦( 10史诗般的Epigrams) (Perlis on Coding Joy ( 10 Epic Epigrams)) Alan J. Perlis was the first recipient of the Turing Award. He’s possibly most remembered today for his Epigrams on Programming, which …

【Android】Activity生命周期(亲测)

测试手机&#xff1a;Nexus 5 系统&#xff1a;4.4 一、测试 测试代码&#xff1a; 1 package com.example.androidalarm;2 3 import android.app.Activity;4 import android.content.Context;5 import android.content.res.Configuration;6 import android.os.Bundle;7 impo…

angularjs 学习笔记 简单基础

angularjs是谷歌公司的一个项目&#xff0c;弥补了hml在构建方面的不足&#xff0c;通过指令&#xff08;directive&#xff09;来扩展html标签&#xff0c;可以使开发者使用html来声明动态内容。 angularjs主要用来开发单页应用&#xff08;SPA&#xff09;为主的项目。 angul…

3-RACSignal 常用方法

RACSingal的常用方法 一 基本使用 1map // 0 创建信号提供者// RACSubject&#xff0c;既能发送信号&#xff0c;又能订阅信号// 多用于代理&#xff0c;相当于OC里的delegate或者回调blockRACSubject *subject [RACSubject subject];// 1 绑定信号RACSignal *bindSignal …

javascript迭代_探索JavaScript迭代

javascript迭代by Festus K. Yangani由Festus K.Yangani 探索JavaScript迭代 (Exploring JavaScript Iteration) Loops allow programs to perform repetitive tasks, such as iterating through an array, while adhering to the DRY principle (Don’t Repeat Yourself). Th…