PHP加密方式分为单项散列加密,对称加密,非对称加密这几类,详细介绍下这三种加密方式。
PHP加密方式分为单项散列加密,对称加密,非对称加密这几类。
常用的MD5、hash、crypt、sha1这种就是单项散列加密,单项散列加密是不可逆的。
URL编码、base64编码这种就是对称加密,是可逆的,就是说加密解密都是用的同一秘钥。
除此外就是非对称加密,加密和解密的秘钥不是同一个,如果从安全性而言,加密的信息如果还想着再解密回来,非对称加密无疑是最为安全的方式。
一、不可逆加密函数
1、md5
string md5 ( string str[,boolraw_output = false ] )
md5()默认情况下以 32 字符十六进制数字形式返回散列值,它接受两个参数,第一个为要加密的字符串,第二个为raw_output的布尔值,默认为false,如果设置为true,md5()则会返回原始的 16 位二进制格式报文摘要。
md5()为单向加密,没有逆向解密算法,但是还是可以对一些常见的字符串通过收集,枚举,碰撞等方法破解,但是破解的字典库是有限的,通过情况下多次md5同时搭配上拼接其他字符后获得的md5值就安全很多。
2、crypt
string crypt ( string str[,stringsalt ] )
crypt()为单向加密,跟md5一样。crypt()接受两个参数,第一个为需要加密的字符串,第二个为盐值(就是加密干扰值,如果没有提供,则默认由PHP自动生成【盐值只能取两位】);返回散列后的字符串或一个少于 13 字符的字符串,后者为了区别盐值。
3、password_hash()
用于创建密码的散列(hash),password_hash() 兼容 crypt()。 crypt() 创建的密码散列也可用于 password_hash()。
string password_hash ( string $password , int $algo [, array $options ] )
参数:$password-用户密码,$algo-密码算法常量,$options-包含有选项的关联数组,默认随机盐值与默认 cost。
4、sha1
string sha1 ( string str[,boolraw_output = false ]
跟md5很像,不同的是sha1()默认情况下返回40个字符的散列值,传入参数性质一样,第一个为加密的字符串,第二个为raw_output的布尔值,默认为false,如果设置为true,sha1()则会返回原始的20 位原始格式报文摘要,sha1()也是单向加密,没有逆向解密算法。
4、hash
string hash($ago,$data);
$ago是可以指定加密使用的哈希算法,例如:"md5","sha256","haval160,4" 等。$data是要加密的数据
hash加密也是不可逆的,因为是给定一个不确定的字符串返回特定长度的字符串,这个本质意义上来说实现了单项散列加密。
二、对称加密
5、Urlencode
string urlencode ( string $str )
一个参数,传入要加密的字符串(通常应用于对URL的加密),
urlencode为双向加密,可以用urldecode来加密(严格意义上来说,不算真正的加密)
返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号( )。
6、base64编码
string base64_decode ( string $encoded_data )
base64_encode()接受一个参数,也就是要编码的数据(这里不说字符串,是因为很多时候base64用来编码图片)
base64_encode()为双向加密,可用base64_decode()来解密
base64加密本质上说就是把数据转换为ASCLL码,比如一个图片进行base64编码就会变成一堆以Ascll码连接的字符串,这会更有利于文件的传输,当然base64的作用在与文件的传输。例如手机客户端上传文件到服务器,使用base64编码可以轻松实现文件的传输。
三、非对称加密
非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
在非对称加密中使用的主要算法有:RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。
1、RSA加密算法
RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送到解密者,解密者用私钥解密将密文解码为明文。
以甲要把信息发给乙为例,首先确定角色:甲为加密者,乙为解密者。首先由乙随机确定一个KEY,称之为密匙,将这个KEY始终保存在机器B中而不发出来;然后,由这个 KEY计算出另一个KEY,称之为公匙。这个公钥的特性是几乎不可能通过它自身计算出生成它的私钥。接下来通过网络把这个公钥传给甲,甲收到公钥后,利用公钥对信息加密,并把密文通过网络发送到乙,最后乙利用已知的私钥,就对密文进行解码了。以上就是RSA算法的工作流程。
算法实现过程为:
a、随意选择两个大的质数p和q,p不等于q,计算N=pq。
b、根据欧拉函数,不大于N且与N互质的整数個数為(p-1)(q-1)。
c、选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1)。
d、用以下这个公式计算d:d× e ≡ 1 (mod (p-1)(q-1))。
e、将p和q的记录销毁。
以上内容中,(N,e)是公钥,(N,d)是私钥。
生成私钥文件:openssl genrsa -out rsa_private_key.pem 1024
利用私钥,生成公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
通过生成的公钥和私钥就可以对数据进行加解密。
示例:
<?php
// 密钥(密码)
$config['digest_alg'] = 'abc';
// 字节数512 1024 2048 4096等不能加引号,此处长度与加密的字符串长度有关系
$config['private_key_bits'] = 512;
// 加密类型
$config['private_key_type'] = OPENSSL_KEYTYPE_RSA;
// 生成一个新的私钥
$res = openssl_pkey_new($config);
// 提取私钥
openssl_pkey_export($res, $private_key);
// 生成公钥
$public_key = openssl_pkey_get_details($res);
// 提取公钥
$public_key = $public_key["key"];
//私钥字符串查看
echo '<b>私钥</b>';echo '<br>';var_dump($private_key);echo '<br>';
//公钥字符串查看
echo '<b>公钥</b>';echo '<br>';var_dump($public_key);echo '<br>';
//要加密的数据
$data = "https://www.yj521.com/";
echo '<b>加密的数据:</b>'.$data.'<br>';
//私钥加密后的数据
openssl_private_encrypt($data,$encrypted,$private_key);
//加密后的内容通常含有特殊字符,需要base64编码转换下
$encrypted = base64_encode($encrypted);
echo "<b>私钥加密后的数据:</b>".$encrypted."<br>";
//公钥解密
openssl_public_decrypt(base64_decode($encrypted), $decrypted, $public_key);
echo "<b>公钥解密后的数据:</b>".$decrypted,"<br>";
//公钥加密后的数据
openssl_public_encrypt($data, $encrypted, $public_key);
$encrypted = base64_encode($encrypted);
echo "<b>公钥加密后的数据:</b>".$encrypted."<br>";
//私钥解密
openssl_private_decrypt(base64_decode($encrypted), $decrypted, $private_key);//私钥解密
echo "<b>私钥解密后的数据:</b>".$decrypted."<br>";
?>