Heim  >  Artikel  >  Backend-Entwicklung  >  浅谈 PHP 中的多种加密技术及代码示例_PHP教程

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

WBOY
WBOYOriginal
2016-07-12 09:06:031266Durchsuche

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

同样是一道面试答错的问题,面试官问我非对称加密算法中有哪些经典的算法? 当时我愣了一下,因为我把非对称加密与单项散列加密的概念弄混淆了,所以更不用说什么非对称加密算法中有什么经典算法,结果当然也让面试官愣了一下,所以今天就花点时间说说PHP中的信息加密技术

信息加密技术的分类

单项散列加密技术(不可逆的加密)

属于摘要算法,不是一种加密算法,作用是把任意长的输入字符串变化成固定长的输出串的一种函数

MD5

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

md5()为单向加密,没有逆向解密算法,但是还是可以对一些常见的字符串通过收集,枚举,碰撞等方法破解;所以为了让其破解起来更麻烦一些,所以我们一般加一点盐值(salt)并双重MD5;

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

sdva就是盐值,该盐值应该是随机的,比如md5常用在密码加密上,所以在注册的时候我会随机生成这个字符串,然后通过上面的方法来双重加密一下;

Crypt

很少看到有人用这个函数,如果要用的话有可能是用在对称或非对称的算法里面,了解一下既可;

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

<ol class="dp-j"><li class="alt"><span><span><?php </span></span></li><li><span>$password=<span class="string">'testtest.com'</span><span>; </span></span></li><li class="alt"><span>echo crypt($password); </span></li><li><span><span class="comment">//输出:$1$DZ3.QX2.$CQZ8I.OfeepKYrWp0oG8L1</span><span> </span></span></li><li class="alt"><span><span class="comment">/*第二个$与第三个$之间的八个字符是由PHP生成的,每刷新一次就变一次</span> </span></li><li><span><span class="comment">*/</span><span> </span></span></li><li class="alt"><span>echo <span class="string">"<hr>"</span><span>; </span></span></li><li><span> </span></li><li class="alt"><span>echo crypt($password,<span class="string">"testtest"</span><span>); </span></span></li><li><span><span class="comment">//输出:tesGeyALKYm3A</span><span> </span></span></li><li class="alt"><span><span class="comment">//当我们要加自定义的盐值时,如例子中的testtest作为第二个参数直接加入, 超出两位字符的会截取前两位</span><span> </span></span></li><li><span>echo <span class="string">"<hr>"</span><span>; </span></span></li><li class="alt"><span> </span></li><li><span>echo  crypt($password,<span class="string">'$1$testtest$'</span><span>); </span></span></li><li class="alt"><span><span class="comment">//输出:$1$testtest$DsiRAWGTHiVH3O0HSHGoL1</span><span> </span></span></li><li><span><span class="comment">/*crypt加密函数有多种盐值加密支持,以上例子展示的是MD5散列作为盐值,该方式下</span> </span></li><li class="alt"><span><span class="comment">盐值以$1$$的形式加入,如例子中的testtest加在后两个$符之间,</span> </span></li><li><span><span class="comment">超出八位字符的会截取前八位,总长为12位;crypt默认就是这种形式。</span> </span></li><li class="alt"><span><span class="comment">*/</span><span> </span></span></li><li><span>echo <span class="string">"<hr>"</span><span>; </span></span></li><li class="alt"><span><span class="comment">//crypt还有多种盐值加密支持,详见手册</span><span> </span></span></li><li><span> </span></li><li class="alt"><span>Sha1加密: </span></li><li><span> </span></li><li class="alt"><span>string sha1 ( string $str [, bool $raw_output = <span class="keyword">false</span><span> ]); </span><span class="comment">//跟md5很像,不同的是sha1()默认情况下返回40个字符的散列值,传入参数性质一样,第一个为加密的字符串,第二个为raw_output的布尔值,默认为false,如果设置为true,sha1()则会返回原始的20 位原始格式报文摘要</span><span> </span></span></li><li><span><?php </span></li><li class="alt"><span>$my_intro=<span class="string">"zhouxiaogang"</span><span>; </span></span></li><li><span>echo sha1($my_intro); <span class="comment">// b6773e8c180c693d9f875bcf77c1202a243e8594</span><span> </span></span></li><li class="alt"><span>echo <span class="string">"<hr>"</span><span>; </span></span></li><li><span><span class="comment">//当然,可以将多种加密算法混合使用</span><span> </span></span></li><li class="alt"><span>echo md5(sha1($my_intro)); </span></li><li><span><span class="comment">//输出:54818bd624d69ac9a139bf92251e381d</span><span> </span></span></li><li class="alt"><span><span class="comment">//这种方式的双重加密也可以提高数据的安全性</span><span> </span></span></li></ol>

非对称加密

非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥public key,简称公钥)和私有密钥private key,简称私钥);

1b4c510fd9f9d72a79ac165bd72a2834359bbbaf.jpg-182.2kB

如图所示,甲乙之间使用非对称加密的方式完成了重要信息的安全传输。

在传输过程中,即使攻击者截获了传输的密文,并得到了乙的公钥,也无法破解密文,因为只有乙的私钥才能解密密文
同样,如果乙要回复加密信息给甲,那么需要甲先公布甲的公钥给乙用于加密,甲自己保存甲的私钥用于解密。

在非对称加密中使用的主要算法有:RSA、Elgamal、背包算法、Rabin、D-H、ECC椭圆曲线加密算法)等。 其中我们最见的算法是RSA算法

以下是从网上摘抄的一段PHP通过openssl实现非对称加密的算法

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

对称加密算法

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以 从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在 安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信性至关重 要。

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

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

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

通过Urlencode函数解决链接中带有&字符引起的问题:

<ol class="dp-j"><li class="alt"><span><span><?php </span></span></li><li><span>$pre_url_encode=<span class="string">"zhougang.com?username=zhougang&password=zhou"</span><span>; </span><span class="comment">//在实际开发中,我们很多时候要构造这种URL,这是没有问题的</span><span> </span></span></li><li class="alt"><span>$url_decode    =<span class="string">"zhougang.com?username=zhou&gang&password=zhou"</span><span>;</span><span class="comment">//但是这种情况下用$_GET()来接受是会出问题的;</span><span> </span></span></li><li><span><span class="comment">/*</span> </span></li><li class="alt"><span><span class="comment">Array</span> </span></li><li><span><span class="comment">(</span> </span></li><li class="alt"><span><span class="comment">  [username] => zhou</span> </span></li><li><span><span class="comment">  [gang] =></span> </span></li><li class="alt"><span><span class="comment">  [password] => zhou</span> </span></li><li><span><span class="comment">)</span> </span></li><li class="alt"><span><span class="comment">*/</span><span> </span></span></li><li><span> </span></li><li class="alt"><span><span class="comment">//如下解决问题:</span><span> </span></span></li><li><span>$username=<span class="string">"zhou&gang"</span><span>; </span></span></li><li class="alt"><span>$url_decode=<span class="string">"zhougang.com?username="</span><span>.urlencode($username).</span><span class="string">"&password=zhou"</span><span>; </span></span></li><li><span>?> </span></li><li class="alt"><span> </span></li><li><span>常见的urlencode()的转换字符 </span></li><li class="alt"><span> </span></li><li><span>?=> %3F </span></li><li class="alt"><span>= => %3D </span></li><li><span>% => %<span class="number">25</span><span> </span></span></li><li class="alt"><span>& => %<span class="number">26</span><span> </span></span></li><li><span>\ => %5C </span></li><li class="alt"><span> </span></li><li><span>base64 </span></li><li class="alt"><span> </span></li><li><span>string base64_decode ( string $encoded_data ) </span></li><li class="alt"><span> </span></li><li><span>    base64_encode()接受一个参数,也就是要编码的数据这里不说字符串,是因为很多时候base64用来编码图片) </span></li><li class="alt"><span> </span></li><li><span>    base64_encode()为双向加密,可用base64_decode()来解密 </span></li><li class="alt"><span> </span></li><li><span>$data=file_get_contents($filename); </span></li><li class="alt"><span>echo base64_encode($data); </span></li><li><span><span class="comment">/*然后你查看网页源码就会得到一大串base64的字符串,</span> </span></li><li class="alt"><span><span class="comment">再用base64_decode()还原就可以得到图片。这也可以作为移动端上传图片的处理方案之一但是不建议这样做哈)</span> </span></li><li><span><span class="comment">*/</span><span> </span></span></li></ol>

严格的来说..这两个函数其实不算是加密,更像是一种格式的序列化

以下是我们PHP程序中常用到的对称加密算法

discuz经典算法 

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

加解密函数encrypt()

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

 



www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1067036.htmlTechArticle浅谈 PHP 中的多种加密技术及代码示例 同样是一道面试答错的问题,面试官问我非对称加密算法中有哪些经典的算法? 当时我愣了一下,因...
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn