浅谈 PHP 中的多种加密技术及代码示例

黄金年代律是风度翩翩道面试答错的难点,面试官问作者非对称加密算法中有如何精粹的算法?
此时自家愣了瞬间,因为自个儿把非对称加密与单项散列加密的定义弄混淆了,所以更不用说什么样非对称加密算法中有哪些优良算法,结果自然也让面试官愣了意气风发晃,所以几近来就花点时间说说PHP中的消息加密技能

概述

加密技巧满含多个要素:算法和密钥。算法是将惯常的音信还能领略的新闻与风流倜傥串数字(密钥)结合,发生不可精晓的密文的步调,密钥是用来对数据开展编码和平解决密的意气风发种算法。在平安保密中,可透过适当的钥加密技能和管理机制来作保网络的音讯通讯安全。

软件的加密与解密是一个可喜的钻研世界,它大概能够与人身自由豆蔻年华种处理器能力紧凑结合——密码学、前后相继设计语言、操作系统、数据构造。而鉴于那样或然那样的原故,对于那意气风发世界的关怀程度直接还地处低温状态。而看雪本事论坛相信会为越多对学识怀有期盼的对象多开辟一条走向那个领域的征程,並且随着拉动那么些圈子的缕缕衍变。

趁着对于安全度的不断需求,对于数据加解密与破解之间的奋见死不救,加解密的点子也在无时无刻产生着变化,来探问以后风行的有些加解密算法。

音信加密技能的分类

哪些是加密本领?

加密技能是电商应用的首要安全保密措施,是最常用的平安全保卫密花招,利用手艺手段把关键的数据形成乱码(加密)传送,达到目标地后再用同风流浪漫或区别的手段还原(解密)。加密能力包涵三个要素:算法和密钥。算法是将惯常的文件(只怕能够领略的音信)与一串数字(密钥)的咬合,发生不可了解的密文的手续,密钥是用来对数码进行编码和平解决码的风姿洒脱种算法。在阳泉保密中,可经过适当的密钥加密本领和管理机制来确定保证互连网的新闻通讯安全。密钥加密技艺的密码体制分成对称密钥体制和非对称密钥体制二种。相应地,对数据加密的技艺分为两类,即对称加密(私人密钥加密)和非对称加密(公开密钥加密)。对称加密以数据加密标准(DES,Data
Encryption
Standard)算法为登峰造极代表,非对称加密日常以LacrosseSA(Rivest
Shamir
Ad1eman)算法为表示。对称加密的加密密钥和平解决密密钥相近,而非对称加密的加密密钥和平解决密密钥不一样,加密密钥能够公开而解密密钥需求保密。

– 加解密定义

加解密的概念是在密码学中的术语,以下为维基百科的定义:

加密(朝鲜语:Encryption)是将公开新闻更换为难以读取的密文内容,使之不足读;唯有具有解密方法的靶子,经由解密进度,技能将密文还原为不奇怪可读的内容。(引自State of Qatar。

解密,或称解码,是密码学中的多个术语,是指将生龙活虎种已经经过加密的言语,解成自身的言语或想要的语言。平常认为解密是加密的风姿浪漫种逆向活动。

1.加密算法平时分为对称性加密算法和非对称性加密算法:对于对称性加密算法,音信接收两方都需事情未发生前知道密匙和加解密算法且其密匙是平等的,之后就是对数据开展
加解密了。非对称算法与之不一致,发送双方A,B事情未发生前均生成一群密匙,然后A将和谐的国有密匙发送给B,B将团结的国有密匙发送给A,就算A要给B发送新闻,则先必要用B的国有密匙举办音讯加密,然后发送给B端,那时候B端再用本身的私人民居房密匙举办消息解密,B向A发送音讯时为相仿的道理。

2.关于公钥私钥和数字具名,
通过贰个出殡和安葬邮件的传说让我们有多个深刻的敞亮,好屌的案例:http://www.blogjava.net/yxhxj2006/archive/2012/10/15/389547.html看完这些以往,
相信您会知道非对称加密在网络传输中的安全性的显示,
当然正是事前说起的https。简单的讲:公钥与私钥的效果是:用公钥加密的内容只好用私钥解密,用私钥加密的剧情只可以用公钥解密。**公钥加密私钥解密,
没难点,也能够说是”公共密钥加密系统”私钥加密公钥解密,平时不这样说,应叫”私钥具名,公钥验证”,也能够说是“公共密钥具名系统”

  • <h1>加解密方法</h1>
    加密音信的二种为主措施 ︰ 对称加密
    (也叫做密钥加密)
    和非对称加密
    (也可以称作公钥加密)。

  • <h2>对称加密</h2>

    • <h4>定义</h4>

    行使单钥密码系统的加密方法,同一个密钥能够况且作为消息的加密和解密,必要对加密和平解决密使用相仿密钥的加密算法。由于其速度快,对称性加密平时在音信发送方须要加密大批量数目时利用。对称性加密也称得上密钥加密。

    • <h4>工作经过</h4>

    上边举个例子来轻便说美赞臣(MeadjohnsonState of Qatar下对称加密的做事进度。甲和乙是黄金年代对事情搭档,他们住在差异的城墙。由于生意上的需求,他们平时会互相邮寄首要的货色。为了确认保证商品的商洛,他们签署制作三个保险盒,将物品放入在那之中。他们制作了两把相像的钥匙分别保管,以便在吸收接纳包裹时用这几个钥匙展开保障盒,以至在邮递货物前用那把钥匙锁上保险盒。

    地点是五个将首要能源安全传递到指标地的思想方法,只要甲乙小心保管好钥匙,那么纵然有人获得保证盒,也无从开辟。这些思想被用到了当代微处理机通讯的消息加密中。在对称加密中,数据发送方将公开(原始数据)和加密密钥一同经过特别加密算法管理后,使其变为复杂的加密密文发送出去。选择方收到密文后,若想解读原来的书文,则须求动用加密密钥及相似算法的逆算法对密文举办解密,手艺使其回复成可读明文。在对称加密算法中,使用的密钥独有多个,发收信双方都应用那几个密钥对数据开展加密和平解决密。

    • <h4>常用算法</h4>

    在对称加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。
    DES是生龙活虎种分组数据加密本事(先将数据分为固定长度的小数据块,之后举行加密),速度超快,适用于大量数目加密,而3DES是生龙活虎种基于DES的加密算法,使用3个分裂密匙对同三个分组数据块进行3次加密,如此以使得密文强度更加高。
    相较于DES和3DES算法来讲,AES算法有着更加高的快慢和财富利用频率,安全等第也相比更高了,被喻为新一代加密标准。

    • <h4>优缺点</h4>

    对称加密算法的帮助和益处是算法公开、总括量小、加密速度快、加密作用高。

    对称加密算法的症结是在数码传送前,发送方和接受方必须签署好秘钥,然后使双方都能保存好秘钥。其次假若一方的秘钥被败露,那么加密新闻也就不安全了。其余,每对顾客每一次使用对称加密算法时,都亟待运用其外人不精晓的独一秘钥,那会使得收、发双方所享有的钥匙数量宏大,密钥管理变为双方的肩负。

  • <h2>非对称加密</h2>

    • <h4>定义</h4>

    与对称加密算法分化,非对称加密算法须要三个密钥:公开密钥(publickey)和个人密钥(privatekey)。公开密钥与民用密钥是部分,假使用公开密钥对数码开展加密,独有用相应的村办密钥技术解密;即使用个人密钥对数码进行加密,那么独有用相应的公开密钥工夫解密。因为加密和平解决密使用的是五个不等的密钥,所以这种算法叫作非对称加密算法。

    • <h4>专门的学问历程</h4>

    如下图所示,甲乙之间利用非对称加密的议程产生了紧要音讯的平安传输。

    图片 1

    非对称加密专门的学业经过轻巧暗暗提示图

    1、乙方生成生龙活虎对密钥(公钥和私钥)并将公钥向其余方公开。
    2、得到该公钥的甲方使用该密钥对机密消息实行加密后再发送给乙方。
    3、乙方再用本身保留的另生机勃勃把专项使用密钥(私钥)对加密后的音讯举办解密。乙方只可以用其专项使用密钥(私钥)解密由相应的公钥加密后的音讯。
    在传输过程中,固然攻击者截获了传输的密文,并获得了乙的公钥,也力无法及破解密文,因为独有乙的私钥技术解密密文。
    相通,假如乙要回复加密音信给甲,那么须要甲先公布甲的公钥给乙用于加密,甲本中国人民保险公司存甲的私钥用于解密。

    • <h4>常用算法</h4>

    在非对称加密中接纳的第后生可畏算法有:TucsonSA、Elgamal、马鞍包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。

    • <h4>优缺点</h4>

    非对称加密的短处是加密和平解决密耗费时间长、速度慢,只符合对一些些数码举行加密。
    非对称加密与对称加密相比较,其安全性更加好:对称加密的通讯双方接纳相通的秘钥,假使一方的秘钥遭走漏,那么一切通讯就能被破解。而非对称加密选取生龙活虎对秘钥,一个用来加密,一个用来解密,并且公钥是青霄白日的,秘钥是友好保留的,没有必要像对称加密那样在通讯在此之前要先同步秘钥。

  • <h1>摘要算法</h1>
    前几日风行的加密方法有

    – MD5加密

    MD5的完备是Message-Digest Algorithm
    5,在90年间初由MIT的电脑科学实验室和TucsonSA Data Security
    Inc发明,经MD2、MD3和MD4迈入而来。

    MD5将随机长度的“字节串”转变来一个128bit的大整数,而且它是三个不可逆的字符串转换算法,换句话说正是,即便你看看源程序和算法描述,也不只怕将四个MD5的值转变回原本的字符串,从数学原理上说,是因为原来的字符串有无穷三个,那有一些象海市蜃楼反函数的数学函数。

    MD5的优质应用是对生机勃勃段Message(字节串卡塔尔国发生fingerprint(指纹卡塔尔(قطر‎,以免止被“窜改”。比如,你将后生可畏段话写在三个叫
    readme.txt文件中,并对那个readme.txt爆发三个MD5的值并记录在案,然后你能够流传这几个文件给人家,外人假设改变了文件中的任何内容,你对这些文件再度总结MD5时就会发觉。假使再有三个第三方的验证部门,用MD5还足以免范文件小编的“抵赖”,那正是所谓的数字签字应用。

    MD5还分布用于加密和平解决密才具上,在不知凡几操作系统中,客商的密码是以MD5值(或相像的别的算法)的主意保留的,
    客户Login的时候,系统是把客户输入的密码总计成MD5值,然后再去和种类中保留的MD5值举办比较,而系统并不“知道”客商的密码是怎么着。

    – RSA加密

    ### 定义

    KugaSA是第二个不仅可以用于数据加密也能用于数字具名的算法。它轻松精通和操作,也很盛行。算法的名字以发明者的名字命名:RonRivest, Adi Shamir 和伦NaderAdleman。但奥迪Q7SA的安全性温昔无法得到理论上的求证。它资历了各个攻击,现今未被统统占有。

    图片 2

    LANDSA算法布局

    ### 分析

    LacrosseSA加密算法是当前最有影响力的公钥加密算法,并且被广泛认为是近些日子最精良的公钥方案之后生可畏。奇骏SA是第二个能同期用于加密和数宇签字的算法,它能够抵抗到最近甘休已知的保有密码攻击,已被ISO推荐为公钥数据加密规范。宝马X3SA加密算法基于叁个丰盛简单易行的数论事实:将八个大素数相乘拾分轻巧,但当时想要,但那时想要对其乘积进行因式分解却无比艰辛,因而得以将乘积公开作为加密密钥。

    切实详尽小说能够参见链接http://witcheryne.iteye.com/blog/2171850http://www.cocoachina.com/bbs/read.php?tid=166990在支付宝支付进程中就利用了SportageSA加密。

    – Base64

    ### 定义

    Base64加密算法是互连网上最分布的用于传输8bit字节代码的编码格局之后生可畏,Base64编码可用以在HTTP景况下传递较长的标志信息。举个例子,在JAVAPE大切诺基SISTENCE系统HIBEMATE中,采取了Base64来将三个较长的独步一时标志符编码为三个字符串,用作HTTP表单和HTTPGETUEnclaveL中的参数。在别的应用程序中,也一再要求把二进制数据编码为相符放在UENVISIONL(富含隐蔽表单域)中的方式。这时,采取Base64编码不仅仅相比简便,同期也具有不可读性,即所编码的数量不会被人用肉眼所一向看看。

    – DES加密

    ### 定义

    DES算法为密码体制中的对称密码体制,又被称呼美利坚同车笠之盟数码加密标准,是1971年美利坚合作国IBM集团研制的相辅相成密码体制加密算法。
    明文按63个人张开分组,密钥长陆十六人,密钥事实上是57位出席DES运算(第8、16、24、32、40、48、56、六15人是校验位,
    使得各种密钥皆有单数个1)分组后的明文组和五贰十一人的密钥按位代表或沟通的点子产生密文组的加密方法。

    图片 3

    DES算法结构

    ### 基本原理

其进口参数有四个:key、data、mode。key为加密解密使用的密钥,data为加密解密的数额,mode为其行事形式。当方式为加密形式时,明文依照六十六人进行分组,变成明文组,key用于对数据加密,当格局为解密情势时,key用于对数码解密。实际行使中,密钥只用到了六16位中的伍拾拾贰个人,那样才享有高的安全性。

单项散列加密本事(不可逆的加密State of Qatar

归属摘要算法,不是大器晚成种加密算法,效用是把放肆长的输入字符串变化成固定长的出口串的意气风发种函数

怎样是对称加密技能?

     
 选用单钥密码系统的加密方法,同二个密钥能够而且作为音信的加密和平解决密,这种加密方法称为对称加密,也称为单密钥加密。供给对加密和平解决密使用同风流罗曼蒂克密钥的加密算法。由于其速度快,对称性加密平常在音讯发送方供给加密一大波多少时选用。对称性加密也称为密钥加密。

     
 所谓对称,正是利用这种加密方法的两侧动用方法用雷同的密钥实行加密和平解决密。密钥是调整加密及解密进程的授命。算法是生机勃勃组法则,规定何以开展加密和平解决密。

     
 由此加密的安全性不仅仅在于加密算法自己,密钥管理的安全性更是根本。因为加密和平解决密都采纳同贰个密钥,如何把密钥安全地传递到解密者手上就成了亟供给缓慢解决的难题。

     
 在对称加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。

分析

DES加密算法是黄金时代种分组密码,以六十个人为分组对数据加密,它的密钥长度是五15人,加密解密用同生机勃勃算法。DES加密算法是对密钥进行保密,而公开算法,包含加密和平解决密算法。那样,唯有领悟了和发送方近似密钥的人工夫解读由DES加密算法加密的密文数据。因而,破译DES加密算法实际上正是寻找密钥的编码。对于57个人长度的密钥来讲,假如用穷举法来扩充搜寻的话,其运算次数为256。
乘胜Computer种类才干的不停升高,DES的安全性比它刚面世时会弱得多,但是从非关键性质的其实出发,还能够以为它是十足的。但是,DES以后仅用于旧类其他评判,而更加多地选择新的加密标准。

MD5

string md5 ( string $str [, bool $raw_output = false ] ); //MD5加密,输入任意长度字符串返回一个唯一的32位字符

md5(卡塔尔国为单向加密,未有逆向解密算法,可是依旧得以对一些布满的字符串通过募集,枚举,碰撞等方法破解;所感到了让其破解起来更麻烦一些,所以大家经常加一点盐值(salt卡塔尔并重复MD5;

md5(md5($password).'sdva');

sdva就算盐值,该盐值应该是随意的,举例md5常用在密码加密上,所以在注册的时候小编会随机生成这么些字符串,然后通过上边的秘技来重新加密一下;

优缺点:

     
 对称加密算法的帮助和益处是算法公开、总计量小、加密速度快、加密作用高。

     
 对称加密算法的弱项是在数额传送前,发送方和接受方必须签定好秘钥,然后使双方都能保存好秘钥。其次要是一方的秘钥被外泄,那么加密音讯也就不安全了。其余,每对客商每趟使用对称加密算法时,都亟待选拔其外人不领悟的独一等秘书钥,那会使得收、发双方所享有的钥匙数量庞大,密钥管理变为双方的肩负。

– SHA1加密

###定义

>安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。

Crypt

少之又少看见有人用那些函数,借使要用的话有超级大可能率是用在对称或非对称的算法里面,驾驭一下既可;

string crypt ( string $str [, string $salt ] ) //第一个为需要加密的字符串,第二个为盐值(就是加密干扰值,如果没有提供,则默认由PHP自动生成);返回散列后的字符串或一个少于 13 字符的字符串,后者为了区别盐值

<?php
$password='testtest.com';
echo crypt($password);
//输出:$1$DZ3.QX2.$CQZ8I.OfeepKYrWp0oG8L1
/*第二个$与第三个$之间的八个字符是由PHP生成的,每刷新一次就变一次
*/
echo "<hr>";

echo crypt($password,"testtest");
//输出:tesGeyALKYm3A
//当我们要加自定义的盐值时,如例子中的testtest作为第二个参数直接加入, 超出两位字符的会截取前两位
echo "<hr>";

echo  crypt($password,'$1$testtest$');
//输出:$1$testtest$DsiRAWGTHiVH3O0HSHGoL1
/*crypt加密函数有多种盐值加密支持,以上例子展示的是MD5散列作为盐值,该方式下
盐值以$1$$的形式加入,如例子中的testtest加在后两个$符之间,
超出八位字符的会截取前八位,总长为12位;crypt默认就是这种形式。
*/
echo "<hr>";
//crypt还有多种盐值加密支持,详见手册

怎么样是非对称加密能力?

       
对称加密算法在加密和平解决密时接受的是同七个秘钥;而非对称加密算法亟待五个密钥来实行加密和平解决密,那七个秘钥是公开密钥(public
key,简单称谓公钥)和私家密钥(private key,简单称谓私钥)。

       
与对称加密算法不同,非对称加密算法必要八个密钥:公开密钥(publickey)和私家密钥(privatekey)。公开密钥与民用密钥是局地,若是用公开密钥对数据开展加密,唯有用相应的私有密钥技巧解密;如果用个人密钥对数据开展加密,那么唯有用相应的公开密钥技艺解密。因为加密和平解决密使用的是多少个不等的密钥,所以这种算法叫作非对称加密算法。

正如图所示,甲乙之间利用非对称加密的方法造成了重大音信的平安传输。

分析

SHA1加密算法能够行使不当先2六16个人的数目输入,并发出叁个1六11人的摘要。输入被剪切为5拾二位的块,并独自管理。162人缓冲器用来保存散列函数的中间和末段结果。缓冲器能够由5个34个人寄放器(A、B、C、D和E)来表示。SHA1是黄金年代种比MD5的安全性强的算法,理论上,凡是利用“音讯摘要”方式的数字印证算法都以有“碰撞”的——也正是三个不等的事物算出的音信摘要相近,互通作弊图正是那般。不过安全性高的算法要找到钦命数量的“碰撞”十分不方便,而利用公式来计量“碰撞”就更不方便一方今停止通用安全算法中唯有MD5被破解。


上面是二个整机的代码示例

#import <Foundation/Foundation.h>
@interface Helper : NSObject
//MD5
+ (NSString *) md5:(NSString *)str;
//Base64
+ (NSString *)base64StringFromText:(NSString *)text;
+ (NSString *)textFromBase64String:(NSString *)base64;
+ (NSString *)base64EncodedStringFrom:(NSData *)data;
//DES加密
+(NSString *)encryptSting:(NSString *)sText key:(NSString *)key andDesiv:(NSString *)ivDes;
//DES解密
+(NSString *)decryptWithDESString:(NSString *)sText key:(NSString *)key andiV:(NSString *)iv;
//AES加密
+ (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data;
//AES解密
+ (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data;
@end

#import "Helper.h"
#import <CommonCrypto/CommonHMAC.h>
#import<CommonCrypto/CommonCryptor.h>
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define LocalStr_None  @""
@implementation Helper

//Md5
+ (NSString *) md5:(NSString *)str {
    if (str == nil) {
        return nil;
    }
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, strlen(cStr), result );
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

//转化为Base64
+ (NSString *)base64StringFromText:(NSString *)text
{
    if (text && ![text isEqualToString:LocalStr_None]) {
        //取项目的bundleIdentifier作为KEY  改动了此处
        //NSString *key = [[NSBundle mainBundle] bundleIdentifier];
        NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
        //IOS 自带DES加密 Begin  改动了此处
        //data = [self DESEncrypt:data WithKey:key];
        //IOS 自带DES加密 End
        return [self base64EncodedStringFrom:data];
    }
    else {
        return LocalStr_None;
    }
}

//由base64转化
+ (NSString *)textFromBase64String:(NSString *)base64
{
    if (base64 && ![base64 isEqualToString:LocalStr_None]) {
        //取项目的bundleIdentifier作为KEY   改动了此处
        //NSString *key = [[NSBundle mainBundle] bundleIdentifier];
        NSData *data = [self dataWithBase64EncodedString:base64];
        //IOS 自带DES解密 Begin    改动了此处
        //data = [self DESDecrypt:data WithKey:key];
        //IOS 自带DES加密 End
        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    else {
        return LocalStr_None;
    }
}

//DES加密
+(NSString *)encryptSting:(NSString *)sText key:(NSString *)key andDesiv:(NSString *)ivDes
{
    if ((sText == nil || sText.length == 0)
        || (sText == nil || sText.length == 0)
        || (ivDes == nil || ivDes.length == 0)) {
        return @"";
    }
    //gb2312 编码
    NSStringEncoding encoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSData* encryptData = [sText dataUsingEncoding:encoding];
    size_t  dataInLength = [encryptData length];
    const void *   dataIn = (const void *)[encryptData bytes];

    CCCryptorStatus ccStatus = nil;
    uint8_t *dataOut = NULL; //可以理解位type/typedef 的缩写(有效的维护了代码,比如:一个人用int,一个人用long。最好用typedef来定义)
    size_t dataOutMoved = 0;
    size_t    dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);  dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
    memset((void *)dataOut, 0x0, dataOutAvailable);//将已开辟内存空间buffer的首 1 个字节的值设为值 0
    const void *iv = (const void *) [ivDes cStringUsingEncoding:NSASCIIStringEncoding];
    //CCCrypt函数 加密/解密
    ccStatus = CCCrypt(kCCEncrypt,//  加密/解密
                       kCCAlgorithmDES,//  加密根据哪个标准(des,3des,aes。。。。)
                       kCCOptionPKCS7Padding,//  选项分组密码算法(des:对每块分组加一次密  3DES:对每块分组加三个不同的密)
                       [key UTF8String],  //密钥    加密和解密的密钥必须一致
                       kCCKeySizeDES,//   DES 密钥的大小(kCCKeySizeDES=8)
                       iv, //  可选的初始矢量
                       dataIn, // 数据的存储单元
                       dataInLength,// 数据的大小
                       (void *)dataOut,// 用于返回数据
                       dataOutAvailable,
                       &dataOutMoved);

    //编码 base64
    NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];
    Byte *bytes = (Byte *)[data bytes];
    //下面是Byte 转换为16进制。
    NSString *hexStr=@"";
    for(int i=0;i<[data length];i++){
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
        if([newHexStr length]==1)
            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
        else
            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
    }
    free(dataOut);
    return hexStr;
}

//DES解密
+(NSString *)decryptWithDESString:(NSString *)sText key:(NSString *)key andiV:(NSString *)iv
{
    if ((sText == nil || sText.length == 0)
        || (sText == nil || sText.length == 0)
        || (iv == nil || iv.length == 0)) {
        return @"";
    }
    const void *dataIn;
    size_t dataInLength;
    char *myBuffer = (char *)malloc((int)[sText length] / 2 + 1);
    bzero(myBuffer, [sText length] / 2 + 1);
    for (int i = 0; i < [sText length] - 1; i += 2) {
        unsigned int anInt;
        NSString * hexCharStr = [sText substringWithRange:NSMakeRange(i, 2)];
        NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr];
        [scanner scanHexInt:&anInt];
        myBuffer[i / 2] = (char)anInt;
    }

    NSData *decryptData =[NSData dataWithBytes:myBuffer length:[sText length] / 2 ];//转成utf-8并decode
    dataInLength = [decryptData length];
    dataIn = [decryptData bytes];
    free(myBuffer);
    CCCryptorStatus ccStatus = nil;
    uint8_t *dataOut = NULL; //可以理解位type/typedef 的缩写(有效的维护了代码,比如:一个人用int,一个人用long。最好用typedef来定义)
    size_t dataOutAvailable = 0; //size_t  是操作符sizeof返回的结果类型
    size_t dataOutMoved = 0;

    dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
    dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
    memset((void *)dataOut, 0x0, dataOutAvailable);//将已开辟内存空间buffer的首 1 个字节的值设为值 0

    const void *ivDes = (const void *) [iv cStringUsingEncoding:NSASCIIStringEncoding];
    //CCCrypt函数 加密/解密
    ccStatus = CCCrypt(kCCDecrypt,//  加密/解密
                       kCCAlgorithmDES,//  加密根据哪个标准(des,3des,aes。。。。)
                       kCCOptionPKCS7Padding,//  选项分组密码算法(des:对每块分组加一次密  3DES:对每块分组加三个不同的密)
                       [key UTF8String],  //密钥    加密和解密的密钥必须一致
                       kCCKeySizeDES,//   DES 密钥的大小(kCCKeySizeDES=8)
                       ivDes, //  可选的初始矢量
                       dataIn, // 数据的存储单元
                       dataInLength,// 数据的大小
                       (void *)dataOut,// 用于返回数据
                       dataOutAvailable,
                       &dataOutMoved);

    NSStringEncoding encoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);

    NSString *result  = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:encoding];
    free(dataOut);
    return result;
}

//AES加密
+ (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data
{
    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCKeySizeAES128+1];
    bzero(ivPtr, sizeof(ivPtr));

    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [data length];
    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    int newSize = 0;

    if(diff > 0)
    {
        newSize = (int)(dataLength + diff);
    }

    char dataPtr[newSize];
    memcpy(dataPtr, [data bytes], [data length]);
    for(int i = 0; i < diff; i++)
    {
        dataPtr[i + dataLength] = 0x00;
    }

    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x00, //No padding
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          dataPtr,
                                          sizeof(dataPtr),
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);

    if(cryptStatus == kCCSuccess)
    {
        //        NSData *data =[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        //        NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    return nil;
}

//AES解密
+ (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data
{
    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCKeySizeAES128+1];
    bzero(ivPtr, sizeof(ivPtr));

    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [data length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          0x00, //No padding
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);

    if(cryptStatus == kCCSuccess)
    {
        //        NSData *data =[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        // NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    return nil;

}

/******************************************************************************
 函数名称 : + (NSData *)dataWithBase64EncodedString:(NSString *)string
 函数描述 : base64格式字符串转换为文本数据
 输入参数 : (NSString *)string
 输出参数 : N/A
 返回参数 : (NSData *)
 备注信息 :
 ******************************************************************************/
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
    if (string == nil)
        [NSException raise:NSInvalidArgumentException format:nil];
    if ([string length] == 0)
        return [NSData data];

    static char *decodingTable = NULL;
    if (decodingTable == NULL)
    {
        decodingTable = malloc(256);
        if (decodingTable == NULL)
            return nil;
        memset(decodingTable, CHAR_MAX, 256);
        NSUInteger i;
        for (i = 0; i < 64; i++)
            decodingTable[(short)encodingTable[i]] = i;
    }

    const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
    if (characters == NULL)     //  Not an ASCII string!
        return nil;
    char *bytes = malloc((([string length] + 3) / 4) * 3);
    if (bytes == NULL)
        return nil;
    NSUInteger length = 0;

    NSUInteger i = 0;
    while (YES)
    {
        char buffer[4];
        short bufferLength;
        for (bufferLength = 0; bufferLength < 4; i++)
        {
            if (characters[i] == '')
                break;
            if (isspace(characters[i]) || characters[i] == '=')
                continue;
            buffer[bufferLength] = decodingTable[(short)characters[i]];
            if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!
            {
                free(bytes);
                return nil;
            }
        }

        if (bufferLength == 0)
            break;
        if (bufferLength == 1)      //  At least two characters are needed to produce one byte!
        {
            free(bytes);
            return nil;
        }

        //  Decode the characters in the buffer to bytes.
        bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
        if (bufferLength > 2)
            bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
        if (bufferLength > 3)
            bytes[length++] = (buffer[2] << 6) | buffer[3];
    }

    bytes = realloc(bytes, length);
    return [NSData dataWithBytesNoCopy:bytes length:length];
}

/******************************************************************************
 函数名称 : + (NSString *)base64EncodedStringFrom:(NSData *)data
 函数描述 : 文本数据转换为base64格式字符串
 输入参数 : (NSData *)data
 输出参数 : N/A
 返回参数 : (NSString *)
 备注信息 :
 ******************************************************************************/
+ (NSString *)base64EncodedStringFrom:(NSData *)data
{
    if ([data length] == 0)
        return @"";

    char *characters = malloc((([data length] + 2) / 3) * 4);
    if (characters == NULL)
        return nil;
    NSUInteger length = 0;

    NSUInteger i = 0;
    while (i < [data length])
    {
        char buffer[3] = {0,0,0};
        short bufferLength = 0;
        while (bufferLength < 3 && i < [data length])
            buffer[bufferLength++] = ((char *)[data bytes])[i++];

        //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
        characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
        characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
        if (bufferLength > 1)
            characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
        else characters[length++] = '=';
        if (bufferLength > 2)
            characters[length++] = encodingTable[buffer[2] & 0x3F];
        else characters[length++] = '=';
    }

    return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}

@end

如上是接口和促成公文, 现在我们来会见调用

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //MD5
    NSString *md5Str = [Helper md5:@"我爱你"];
    NSLog(@"md5Str is %@",md5Str);//Log is 4F2016C6B934D55BD7120E5D0E62CCE3

    //Base64
    NSString *Base64Str = [Helper base64StringFromText:@"我爱你"];
    NSLog(@"Base64Str is %@",Base64Str);//Log is 5oiR54ix5L2g

    NSString *oriBase64Str = [Helper textFromBase64String:Base64Str];
    NSLog(@"oriBase64Str is %@",oriBase64Str);//Log is  我爱你

    //DES
    NSString *desEnStr = [Helper encryptSting:@"我爱你" key:@"521" andDesiv:@"521"];
    NSLog(@"desEnStr is %@",desEnStr);//Log is  389280aa791ee933
    NSString *desDeStr =[Helper decryptWithDESString:desEnStr key:@"521" andiV:@"521"];
    NSLog(@"desDeStr is %@",desDeStr);//Log is  我爱你

    //AES
    NSData *aesEnData = [Helper AES128EncryptWithKey:@"521" iv:@"521" withNSData:[@"我爱你" dataUsingEncoding:NSUTF8StringEncoding]];
    NSString *aesEnStr = [Helper base64EncodedStringFrom:aesEnData];
    NSLog(@"aesEnStr is %@",aesEnStr);//Log is HZKhnRLlQ8XjMjpelOAwsQ==

    NSData *aesDeData = [Helper AES128DecryptWithKey:@"521" iv:@"521" withNSData:aesEnData];
    NSString *aesDEStr = [Helper base64EncodedStringFrom:aesDeData];
    NSString *result = [Helper textFromBase64String:aesDEStr];
    NSLog(@"aesDEStr is %@ and result is %@",aesDEStr,result);//Log is aesDEStr is 5oiR54ix5L2gAAAAAAAAAA== and result is 我爱你

    return YES;
}

参照文章:
常用加解密工夫介绍
各个加解密算法相比
两种常用加密算法相比较
对称加密和非对称加密介绍和差异
和平安有关的那么些事(非对称加密、数字摘要、数字署名、数字证书、SSL、HTTPS及任何卡塔尔(قطر‎
3个著名加密算法(MD5、HavalSA、DES卡塔尔国的深入分析
iOS–加解密(对称,非对称)(AES DES
base64这里都有State of Qatar,数字具名,cookie

Sha1加密:

string sha1 ( string $str [, bool $raw_output = false ]); //跟md5很像,不同的是sha1()默认情况下返回40个字符的散列值,传入参数性质一样,第一个为加密的字符串,第二个为raw_output的布尔值,默认为false,如果设置为true,sha1()则会返回原始的20 位原始格式报文摘要
<?php
$my_intro="zhouxiaogang";
echo sha1($my_intro); // b6773e8c180c693d9f875bcf77c1202a243e8594
echo "<hr>";
//当然,可以将多种加密算法混合使用
echo md5(sha1($my_intro));
//输出:54818bd624d69ac9a139bf92251e381d
//这种方式的双重加密也可以提高数据的安全性

加解密进程:

非对称加密职业经过容易暗暗表示图

图片 4

1、乙方生成意气风发对密钥(公钥和私钥)并将公钥向其余方公开。

2、得到该公钥的甲方使用该密钥对机密音讯进行加密后再发送给乙方。

3、乙方再用自个儿童卫生保健留的另风华正茂把专项使用密钥(私钥)对加密后的新闻实行解密。乙方只好用其专项使用密钥(私钥)解密由相应的公钥加密后的音讯。

在传输进度中,尽管攻击者截获了传输的密文,并拿走了乙的公钥,也不能破解密文,因为独有乙的私钥工夫解密密文。

同等,假设乙要回复加密音讯给甲,那么供给甲先宣布甲的公钥给乙用于加密,甲自身保存甲的私钥用于解密。

非对称加密

非对称加密算法须要七个密钥来张开加密和解密,那五个秘钥是公开密钥(public
key,简单称谓公钥)和私家密钥(private key,简单称谓私钥);

图片 5

如图所示,甲乙之间利用非对称加密的艺术产生了第风流罗曼蒂克音信的平安传输。

  1. 乙方生成黄金年代对密钥(公钥和私钥)并将公钥向任何方公开。
  2. 获取该公钥的甲方使用该密钥对机密音信实行加密后再发送给乙方。
  3. 乙方再用本中国人民保险公司留的另生机勃勃把专项使用密钥(私钥)对加密后的音讯举行解密。乙方只可以用其专项使用密钥(私钥)解密由相应的公钥加密后的新闻。

在传输进程中,纵然攻击者截获了传输的密文,并获得了乙的公钥,也无从破解密文,因为唯有乙的私钥技巧解密密文
一点差异也未有于,要是乙要回复加密消息给甲,那么要求甲先发表甲的公钥给乙用于加密,甲本身保存甲的私钥用于解密。

在非对称加密中应用的首要算法有:GranCabrioSA、Elgamal、公文包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。 在那之中大家最见的算法是WranglerSA算法

以下是从网络摘抄的黄金时代段PHP通过openssl完成非对称加密的算法

<?php
/**
 * 使用openssl实现非对称加密
 * @since 2010-07-08
 */
class Rsa {
    /**
     * private key
     */
    private $_privKey;
    /**
     * public key
     */
    private $_pubKey;
    /**
     * the keys saving path
     */
    private $_keyPath;
    /**
     * the construtor,the param $path is the keys saving path
     */
    public function __construct($path) {
        if (empty($path) || !is_dir($path)) {
            throw new Exception('Must set the keys save path');
        }
        $this->_keyPath = $path;
    }
    /**
     * create the key pair,save the key to $this->_keyPath
     */
    public function createKey() {
        $r = openssl_pkey_new();
        openssl_pkey_export($r, $privKey);
        file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key', $privKey);
        $this->_privKey = openssl_pkey_get_public($privKey);
        $rp = openssl_pkey_get_details($r);
        $pubKey = $rp['key'];
        file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key', $pubKey);
        $this->_pubKey = openssl_pkey_get_public($pubKey);
    }
    /**
     * setup the private key
     */
    public function setupPrivKey() {
        if (is_resource($this->_privKey)) {
            return true;
        }
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key';
        $prk = file_get_contents($file);
        $this->_privKey = openssl_pkey_get_private($prk);
        return true;
    }
    /**
     * setup the public key
     */
    public function setupPubKey() {
        if (is_resource($this->_pubKey)) {
            return true;
        }
        $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key';
        $puk = file_get_contents($file);
        $this->_pubKey = openssl_pkey_get_public($puk);
        return true;
    }
    /**
     * encrypt with the private key
     */
    public function privEncrypt($data) {
        if (!is_string($data)) {
            return null;
        }
        $this->setupPrivKey();
        $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }
    /**
     * decrypt with the private key
     */
    public function privDecrypt($encrypted) {
        if (!is_string($encrypted)) {
            return null;
        }
        $this->setupPrivKey();
        $encrypted = base64_decode($encrypted);
        $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }
    /**
     * encrypt with public key
     */
    public function pubEncrypt($data) {
        if (!is_string($data)) {
            return null;
        }
        $this->setupPubKey();
        $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }
    /**
     * decrypt with the public key
     */
    public function pubDecrypt($crypted) {
        if (!is_string($crypted)) {
            return null;
        }
        $this->setupPubKey();
        $crypted = base64_decode($crypted);
        $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }
    public function __destruct() {
        @fclose($this->_privKey);
        @fclose($this->_pubKey);
    }
}
//以下是一个简单的测试demo,如果不需要请删除
$rsa = new Rsa('ssl-key');
//私钥加密,公钥解密
echo 'source:我是老鳖<br />';
$pre = $rsa->privEncrypt('我是老鳖');
echo 'private encrypted:<br />' . $pre . '<br />';
$pud = $rsa->pubDecrypt($pre);
echo 'public decrypted:' . $pud . '<br />';
//公钥加密,私钥解密
echo 'source:干IT的<br />';
$pue = $rsa->pubEncrypt('干IT的');
echo 'public encrypt:<br />' . $pue . '<br />';
$prd = $rsa->privDecrypt($pue);
echo 'private decrypt:' . $prd;
?>

优缺点:

非对称加密与对称加密相对来说,其安全性更加好:对称加密的通讯双方动用相仿的秘钥,要是一方的秘钥遭败露,那么万事通讯就能够被破解。而非对称加密利用大器晚成对秘钥,多个用来加密,三个用来解密,何况公钥是当着的,秘钥是慈祥保留的,无需像对称加密那么在通讯从前要先同步秘钥。

非对称加密的劣势是加密和平解决密成本时间长、速度慢,只切合对一点点数量实行加密。

在非对称加密中选择的重要算法有:RSA、Elgamal、托特包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。

对称加密算法

对称加密(也叫私钥加密State of Qatar指加密和解密使用同意气风发密钥的加密算法。临时又叫古板密码算法,便是加密密钥能够从解密密钥中推算出来,同期解密密钥也得以从加密密钥中推算出来。而在大多的对称算法中,加密密钥和平解决密密钥是千篇生机勃勃律的,所以也称这种加密算法为机要密钥算法或单密钥算法。它须求发送方和选择方在平安通讯从前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就表示任哪个人都能够对她们发送或选择的新闻解密,所以密钥的保密性对通讯性至关主要。

对称加密的常用算法有:
DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法

在PHP中也是有包装好的对称加密函数

Urlencode/Urldecode

string urlencode ( string $str ) 
/*
1. 一个参数,传入要加密的字符串(通常应用于对URL的加密)
2. urlencode为双向加密,可以用urldecode来加密(严格意义上来说,不算真正的加密,更像是一种编码方式)
3. 返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。
*/

透过Urlencode函数解决链接中含有&字符引起的主题素材:

<?php
$pre_url_encode="zhougang.com?username=zhougang&password=zhou"; //在实际开发中,我们很多时候要构造这种URL,这是没有问题的
$url_decode    ="zhougang.com?username=zhou&gang&password=zhou";//但是这种情况下用$_GET()来接受是会出问题的;
/*
Array
(
  [username] => zhou
  [gang] => 
  [password] => zhou
)
 */

//如下解决问题:
$username="zhou&gang";
$url_decode="zhougang.com?username=".urlencode($username)."&password=zhou";
?>

广大的urlencode(State of Qatar的转换字符

?=> %3F
= => %3D
% => %25
& => %26
 => %5C

base64

string base64_decode ( string $encoded_data )
  1. base64_encode(卡塔尔(قطر‎采用三个参数,也便是要编码的数量(这里不说字符串,是因为众多时候base64用来编码图片)
  2. base64_encode(卡塔尔为双向加密,可用base64_decode()来解密

$data=file_get_contents($filename);
echo base64_encode($data);
/*然后你查看网页源码就会得到一大串base64的字符串,
再用base64_decode()还原就可以得到图片。这也可以作为移动端上传图片的处理方案之一(但是不建议这样做哈)
*/

严俊的来讲..那八个函数其实不算是加密,更疑似生龙活虎种格式的系列化

以下是我们PHP程序中常用到的相反相成加密算法

discuz卓绝算法

<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {   
    // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙   
    $ckey_length = 4;   

    // 密匙   
    $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);   

    // 密匙a会参与加解密   
    $keya = md5(substr($key, 0, 16));   
    // 密匙b会用来做数据完整性验证   
    $keyb = md5(substr($key, 16, 16));   
    // 密匙c用于变化生成的密文   
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): 
substr(md5(microtime()), -$ckey_length)) : '';   
    // 参与运算的密匙   
    $cryptkey = $keya.md5($keya.$keyc);   
    $key_length = strlen($cryptkey);   
    // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b), 
//解密时会通过这个密匙验证数据完整性   
    // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确   
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) :  
sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;   
    $string_length = strlen($string);   
    $result = '';   
    $box = range(0, 255);   
    $rndkey = array();   
    // 产生密匙簿   
    for($i = 0; $i <= 255; $i++) {   
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);   
    }   
    // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度   
    for($j = $i = 0; $i < 256; $i++) {   
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;   
        $tmp = $box[$i];   
        $box[$i] = $box[$j];   
        $box[$j] = $tmp;   
    }   
    // 核心加解密部分   
    for($a = $j = $i = 0; $i < $string_length; $i++) {   
        $a = ($a + 1) % 256;   
        $j = ($j + $box[$a]) % 256;   
        $tmp = $box[$a];   
        $box[$a] = $box[$j];   
        $box[$j] = $tmp;   
        // 从密匙簿得出密匙进行异或,再转成字符   
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));   
    }   
    if($operation == 'DECODE') {  
        // 验证数据有效性,请看未加密明文的格式   
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&  
substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {   
            return substr($result, 26);   
        } else {   
            return '';   
        }   
    } else {   
        // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因   
        // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码   
        return $keyc.str_replace('=', '', base64_encode($result));   
    }   
}

加解密函数encrypt()

<?php
//$string:需要加密解密的字符串;$operation:判断是加密还是解密,E表示加密,D表示解密;$key:密匙
function encrypt($string,$operation,$key=''){ 
    $key=md5($key); 
    $key_length=strlen($key); 
      $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string; 
    $string_length=strlen($string); 
    $rndkey=$box=array(); 
    $result=''; 
    for($i=0;$i<=255;$i++){ 
           $rndkey[$i]=ord($key[$i%$key_length]); 
        $box[$i]=$i; 
    } 
    for($j=$i=0;$i<256;$i++){ 
        $j=($j+$box[$i]+$rndkey[$i])%256; 
        $tmp=$box[$i]; 
        $box[$i]=$box[$j]; 
        $box[$j]=$tmp; 
    } 
    for($a=$j=$i=0;$i<$string_length;$i++){ 
        $a=($a+1)%256; 
        $j=($j+$box[$a])%256; 
        $tmp=$box[$a]; 
        $box[$a]=$box[$j]; 
        $box[$j]=$tmp; 
        $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256])); 
    } 
    if($operation=='D'){ 
        if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8)){ 
            return substr($result,8); 
        }else{ 
            return''; 
        } 
    }else{ 
        return str_replace('=','',base64_encode($result)); 
    } 
}
?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注