php常用加密函数和算法

♀尐吖头ヾ 提交于 2020-03-19 03:12:10

关键词:
不可逆:
md5(); 计算字符串的 MD5 散列值 不可逆 默认返回32位的16进制
crypt(); 单向字符串散列 可以混淆盐值 不可逆
sha1(); 计算字符串的 sha1 散列值 默认返回值是一个 40 字符长度的十六进制数字。 不可逆
hash() hash($ago,$data); $ago是可以指定加密使用的哈希算法,例如:"md5","sha256","haval160,4" 等。$data是要加密的数据 不可逆
password_hash() – 对密码加密. $hash = password_hash($passwod, PASSWORD_DEFAULT); 现在PHP的官方都是推荐这种方式来加密用户的密码,很多流行的框架比如Laravel就是用的这种加密方式。

可逆:
URL编码加密 urlencode() urldecode() url传递 保护特殊字符串使用 $str="http://guojiadong.com?name=".urlencode('guojiadong&123'); 可逆
Base64编码加密 base64_encode() base64_decode() base64加密本质上说就是把数据转换为ASCLL码 ,这会更有利于文件的传输,当然base64的作用在与文件的传输 可逆

PHP的openssl扩展
openssl扩展使用openssl加密扩展包,封装了多个用于加密解密相关的PHP函数,极大地方便了对数据的加密解密。 常用的函数有:
对称加密相关:
AES 对称加密
https://blog.csdn.net/fangkang7/article/details/94607123
string openssl_encrypt ( string $data , string $method , string $password)
string openssl_decrypt($encrypted, 'aes-128-ecb', base64_decode($key), OPENSSL_RAW_DATA);

RSA 非对称加密 一对公私钥
https://www.cnblogs.com/makalochen/p/10845033.html

openssl_pkey_get_public() 从证书中提取公钥
openssl_pkey_get_private() 从证书中提取私钥
openssl_public_encrypt() 公钥加密
openssl_private_decrypt() 私钥解密
openssl_private_encrypt() 私钥加密
openssl_public_decrypt() 公钥解密
base64_encode() 使用base64对数据重新编码
base64_decode() 将base64的数据解码

https://blog.csdn.net/qq_38483191/article/details/80513448
https://www.jianshu.com/p/c15233d99fa8
https://www.jb51.net/article/170082.htm
https://www.jb51.net/article/128149.htm
/*
加密算法一般分为两种:对称加密算法和非对称加密算法。
对称加密
对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,
接收者使用同样的密匙解密,获取信息。常见的对称加密算法有:des/aes/3des.
对称加密算法的特点有:速度快,加密前后文件大小变化不大,但是密匙的保管是个大问题
,因为消息发送方和接收方任意一方的密匙丢失,都会导致信息传输变得不安全。
非对称加密
与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙
分为公匙和私匙,私匙自己安全保存,而将公匙公开。公钥与私钥是一对,如果用公钥对数据进行加密,
只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密发送数据前只需要使用接收方的公匙加密就行了。
常见的非对称加密算法有RSA/DSA:非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候我们还需要对大块数据进行分块加密。
数字签名
为了保证数据的完整性,还需要通过散列函数计算得到一个散列值,这个散列值被称为数字签名。其特点有:
无论原始数据是多大,结果的长度相同的;
输入一样,输出也相同;
对输入的微小改变,会使结果产生很大的变化;
加密过程不可逆,无法通过散列值得到原来的数据;
常见的数字签名算法有md5,hash1等算法。
PHP的openssl扩展
openssl扩展使用openssl加密扩展包,封装了多个用于加密解密相关的PHP函数,极大地方便了对数据的加密解密。 常用的函数有:
对称加密相关:
string openssl_encrypt ( string $data , string $method , string $password)
其中$data为其要加密的数据,$method是加密要使用的方法,$password是要使用的密匙,函数返回加密后的数据;
其中$method列表可以使用openssl_get_cipher_methods()来获取
其解密函数为 string openssl_encrypt ( string $data , string $method , string $password)
非对称加密相关:
它们都只需要传入证书文件(一般是.pem文件);
使用公匙加密数据,其中$data是要加密的数据;$crypted是一个引用变量,加密后的数据会被放入这个变量中;$key是要传入的公匙数据;
由于被加密数据分组时,有可能不会正好为加密位数bit的整数倍,所以需要$padding(填充补齐),
$padding的可选项有 OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING,分别为PKCS1填充,或不使用填充;
签名函数:$data为要签名的数据;$signature为签名结果的引用变量;$priv_key_id为签名所使用的私匙;$signature_alg为签名要使用的算法
,其算法列表可以使用openssl_get_md_methods()得到
验签函数:与签名函数相对,只不过它要传入与私匙对应的公匙;其结果为签名验证结果,1为成功,0为失败,-1则表示错误;

  • /
    /
  • 基于百度云API的例子
  • 密码一律采用AES 128位加密算法进行加密,用SK的前16位作为密钥,
  • 加密后生成的二进制字节流需要转成十六进制,并以字符串的形式传到服务端
  • */
    function aes128WithFirst16Char($adminPass, $secretAccessKey)
    {
    $adminPass = pkcs5Pad($adminPass);
    //把key值截取成16位的
    $secretAccessKey = substr($secretAccessKey, 0, 16);
    //进行AES加密
    $crypted = openssl_encrypt($adminPass, 'AES-128-ECB', $secretAccessKey, OPENSSL_RAW_DATA);
    //把字符串转换为16进制
    return bin2hex(substr($crypted, 0, 16));
    }
    //把密码填充成16位
    function pkcs5Pad($adminPass)
    {
    $pad = 16 - (strlen($adminPass) % 16);
    return $adminPass . str_repeat(chr($pad), $pad);
    }
    echo aes128WithFirst16Char('加密的密码','key值');

前言

PHP加密方式分为单项散列加密,对称加密,非对称加密这几类。像常用的MD5、hash、crypt、sha1这种就是单项散列加密,单项散列加密是不可逆的。像URL编码、base64编码这种就是对称加密,是可逆的,就是说加密解密都是用的同一秘钥。除此外就是非对称加密,加密和解密的秘钥不是同一个,如果从安全性而言,加密的信息如果还想着再解密回来,非对称加密无疑是最为安全的方式。

MD5加密

md5加密算法在PHP中是最常见的加密算法,这个算法是不可逆的,通常用于加密用户的密码等信息来保证用户的信息安全。来自 RFC 1321 的解释 - MD5 报文摘要算法:MD5 报文摘要算法将任意长度的信息作为输入值,并将其换算成一个 128 位长度的"指纹信息"或"报文摘要"值来代表这个输入值,并以换算后的值作为结果。MD5 算法主要是为数字签名应用程序而设计的;在这个数字签名应用程序中,较大的文件将在加密(这里的加密过程是通过在一个密码系统下[如:RSA]的公开密钥下设置私有密钥而完成的)之前以一种安全的方式进行压缩。好,来举个例子

<?php

//这里是一个字符串

$str="this is zifuchuan";

//通过MD5加密函数加密

$res=md5($str);//在PHP中,MD5()函数还有第二个参数,为bool类型,当为TRUE是返回的加密是16字符原始//二进制格式字符串,当为FALSE是返回32位的16进制,默认为false,一般都默认//返回二进制

$res=md5($str,true);

?>

Crypt()加密算法

crypt()加密算法是一种不可逆的加密算法,他有两个参数,一个是需要加密的字符串,另外一个是盐值(或者成为干扰字符串),如果没有指定第二个参数那么将自己随机生成一个干扰字符串并且是以MD5加密的方式。另外这个函数在不同的操作系统上的表现形式也是不一样的,会自动检测。举个例子。

<?php

//需要加密的字符串

$str="this is string";

//使用crypt加密,不指定盐值

$res=crypt($str);//指定盐值,但是盐值只能写两位,如果超过了则只会取前两位,在某些系统中会直接返回FALSE

$res=crypt($str,'jm');

?>

sha1加密算法

sha1加密算法和MD5加密算法一样时不可逆的,有两个参数,一个是要加密的字符串,第二个是bool值,如果指定第二个参数为TRUE,则返回二进制格式的字符串,如果不指定则默认为FALSE,返回的是40位的16进制格式的字符串,举个例子

<?php

//需要加密的字符串

$str="this is string";

//通过sha1进行加密

$res=sha1($str);

//通过指定第二个参数加密

$res=sha1($str,true);

?>

URL编码加密

对于我们的网站,直接暴露给用户的就是地址栏的传参,对于这一部分都是明文的,所以我们可以使用基本的加密算法来简单加密一下,注意,此种方式加密是可逆的,也就是说加密后的密文我们可以解密之后看到,所以如果你想实现真正的加密,并不推荐这个加密算法。

在PHP中对于URL加密解密用到两个函数urlencode和urldecode.

http://www.guojiadong.com?name=guojiadong&amp;amp;phone=112

我们就可以对这段地址进行加密

<?php

//需要加密的网址

$str = "http://www.guojiadong.com?name=guojiadong&phone=112";

//使用urlencode加密

$res = urlencode($str);

//使用urldecode解密

$result = urldecode($res);

?>

既然通过这种方式加密解密并且加密之后也并没有什么太大的区别,我们需要他的目的是什么呢?我们想对于想破解这串加密的字符串可以轻松的破解,其实这两个函数有他特殊的作用,也就是说除了加密的作用,当然了这是题外话,因为本主题主要是加密,但是作为扩展还是要说一下。

<?php

//在HTML传参到后台中的时候如果我们想把&作为参数传到后台,在没有加密之前,浏览器会把他作为

//参数分隔符

//例如:http://guojiadong.com?name=guojiadong&amp;123,

我们想把guojiadong&amp;123作为参数传给

//后台,这个时候直接这样写后台得到的数据却只得到name的值为guojiadong,而123确作为变量

//当然了用一个数字做变量是不合法的,但是浏览器确并不这么智能的区分他

//为了解决这个问题我们就可以对这部分字符编码

$str="http://guojiadong.com?name=".urlencode('guojiadong&123');

//这样我们传过来的值就变成了name = guojiadong&123

?>

Base64编码加密

大家注意,虽然base64写到本节加密算法中,但是他并不是主要用来加密的,而且从大多数的程序来说,几乎没有人会用他作为加密手段来加密数据,那么他的作用主要是用于做什么呢?这要说的base64加密的机制了。

base64加密本质上说就是把数据转换为ASCLL码,比如一个图片进行base64编码就会变成一堆以Ascll码连接的字符串,这会更有利于文件的传输,当然base64的作用在与文件的传输。例如手机客户端上传文件到服务器,使用base64编码可以轻松实现文件的传输。

base64加密函数

base64_encode($data);

base64解密函数

base64_decode($data);

hash加密

hash加密也是不可逆的,因为是给定一个不确定的字符串返回特定长度的字符串,这个本质意义上来说实现了单项散列加密。使用方法

hash($ago,$data);

$ago是可以指定加密使用的哈希算法,例如:"md5","sha256","haval160,4" 等。

$data是要加密的数据

Password Hashing API 加密

Password Hashing API是PHP 5.5之后才有的新特性,它主要是提供下面几个函数供我们使用:

password_hash() – 对密码加密.

password_verify() – 验证已经加密的密码,检验其hash字串是否一致.

password_needs_rehash() – 给密码重新加密.

password_get_info() – 返回加密算法的名称和一些相关信息.

虽然说crypt()函数在使用上已足够,但是password_hash()不仅可以使我们的代码更加简短,而且还在安全方面给了我们更好的保障,所以,现在PHP的官方都是推荐这种方式来加密用户的密码,很多流行的框架比如Laravel就是用的这种加密方式。

$hash = password_hash($passwod, PASSWORD_DEFAULT);

对,就是这么简单,一行代码,All done。

PASSWORD_DEFAULT目前使用的就是Bcrypt,所以在上面我会说推荐这个,不过因为Password Hashing API做得更好了,我必须郑重地想你推荐Password Hashing API。这里需要注意的是,如果你代码使用的都是PASSWORD_DEFAULT加密方式,那么在数据库的表中,password字段就得设置超过60个字符长度,你也可以使用PASSWORD_BCRYPT,这个时候,加密后字串总是60个字符长度。

这里使用password_hash()你完全可以不提供盐值(salt)和 消耗值 (cost),你可以将后者理解为一种性能的消耗值,cost越大,加密算法越复杂,消耗的内存也就越大。当然,如果你需要指定对应的盐值和消耗值,你可以这样写:

$options = [

'salt' => custom_function_for_salt(), //write your own code to generate a suitable salt

'cost' => 12 // the default cost is 10 ];

$hash = password_hash($password, PASSWORD_DEFAULT, $options);

密码加密过后,我们需要对密码进行验证,以此来判断用户输入的密码是否正确:

if (password_verify($password, $hash)) {

// Pass }

else {

// Invalid

}

很简单的吧,直接使用password_verify就可以对我们之前加密过的字符串(存在数据库中)进行验证了。

然而,如果有时候我们需要更改我们的加密方式,如某一天我们突然想更换一下盐值或者提高一下消耗值,我们这时候就要使用到password_needs_rehash()函数了:

if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {

// cost change to 12 $hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);

// don't forget to store the new hash!

}

只有这样,PHP的Password Hashing API才会知道我们重现更换了加密方式,这样的主要目的就是为了后面的密码验证。

简单地说一下password_get_info(),这个函数一般可以看到下面三个信息:

algo – 算法实例

algoName – 算法名字

options – 加密时候的可选参数

作者:栋公子
链接:https://www.jianshu.com/p/c15233d99fa8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!