咱们曾经学过不少 PHP 中加密扩大相干的内容了。而明天开始,咱们要学习的则是重点中的重点,那就是 OpenSSL 加密扩大的应用。为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚至是整个开发圈中的数据加密事实标准,包含 HTTPS/SSL 在内的加密都是它的理论利用,二是 OpenSSL 提供了对称和非对称加密的模式,也就是咱们日常中最广泛的两种加密形式,这都是咱们须要把握的内容。
那么,它和 Hash 类的加密有什么不同吗?Hash 类的加密是单向的不可逆转的加密,加密后的内容是 16 进制 的 Hash 串,咱们只能通过彩虹表去反推明文内容,所以只有加上盐值或者多套两层加密,就十分难逆向破解进去了。因而,Hash 加密通常会用于用户的明码保留上,即便数据库泄露了用户明码也仍然是平安的。而 OpenSSL 这种类型的对称 / 非对称加密则是能够通过某个关键字或者证书来进行正向加密和逆向解密的,原文都是能够失去的。上面咱们就来具体说说对称和非对称加密的问题。
什么是对称和非对称加密
对称加密,通常是通过一个 key(密钥)来对原文进行加密。也就是说,不论是服务端还是客户端或是其它的任何对端,在两端通信时,它们传输的加密内容都必须要应用雷同的 key 来进行加 / 解密操作。两端都必须同时保留这样一个 key。预计大家也想到了,当初不论是 web 开发还是 app 开发,代码都是能够反编译查看到源码的。如果应用对称加密的话,key 是很容易被获取到的。不过,对称加密的益处是速度十分快,不耗费资源。
非对称加密则是两端持有不同的 key。就像咱们平时见到的最多的 https 证书,就是别离有 公钥 和 私钥 这两个概念。个别咱们会应用 公钥 进行加密,而后应用 私钥 进行解密,通常 公钥 都是公开并发送给对方的,而私钥是保留在本人这里的。也就是说,对方向咱们发送数据的时候,应用咱们给它的公钥将数据进行加密,数据在传输过程中就十分平安,因为两头并没有他人有能够解密这段数据的私钥,直到咱们接管到数据后应用本人的私钥进行解密后就失去了原文数据。因为两边的密钥内容并不相同,所以绝对于对称加密来说,非对称加密的安全性要高了很多。尽管说非对称加密的算法和复杂度都比对称加密晋升了好几个品位,但绝对于对称加密的劣势,在非对称加密中,速度和性能也就成了它的瓶颈,特地是数据量大的状况下。另外,非对称加密的数学原理是 大数难合成 问题,也就是越大的数越难进行因子合成,如果某个算法能在短时间内破解这个问题的话,那么祝贺你,古代加密算法的根底天花板就被你捅破了。
对称加密罕用的算法有:AES、DES、3DES、IDEA、RC2、RC5 等,比拟罕用的是 AES 和 DES。
非对称加密罕用的算法有:RSA、Elgamal、ECC 等,RSA 十分罕用和广泛,SSL 和一些证书算法都是基于 RSA。
为了系统安全咱们应该怎么办?
那么,咱们有没有折衷的形式来应用这两种加密能力呢?当然有了,并且也是十分经典的一种技术:数字信封。
其实意思非常简单,就是利用这两种加密形式各自的长处。非对称加密的安全性高,但速度慢,而且数据量越大速度越慢,那么咱们就用它来加密对称加密的 key,通常这个 key 不会很大。而后理论的数据实体应用这个对称加密的 key 来进行对称加密晋升速度。这样,咱们发送给客户端时,就包含两个内容,一个是非对称加密进行加密的 key,一个应用对称加密进行加密的数据内容。客户端拿到信息后,首先应用非对称加密的密钥解码出对称加密的 key,而后再应用这个 key 来解密最终的数据内容。是不是说得很晕?咱们通过一张图来看看,或者大家就高深莫测了。
其中,公钥和私钥就不必多解释了。会话密钥就是咱们的对称加密算法的密钥 key。联合上面对数字信封传输过程的解释,大家应该就能看懂了吧。
OpenSSL 扩大的对称加密
好了,介绍这么多理论知识,接下来还是回归正题了,咱们在 PHP 中如何实现对称和非对称加密呢?非常简单,应用 OpenSSL 扩大就能够了。这个扩大也是随 PHP 源码一起公布的,编译装置的时候加上 –with-openssl 就能够了。当然,它也是须要零碎环境中装置 OpenSSL 软件的,在各类操作系统中根本都曾经间接有了,如果没有的话就本人装置一下即可。最简略的,在操作系统命令行看看有没有 openssl 命令就能够看出以后零碎有没有装置 OpenSSL 相干的软件。
[root@localhost ~]# openssl version
OpenSSL 1.1.1 FIPS 11 Sep 2018
明天,咱们次要学习的还是比较简单的对称加密相干的函数。
对称加 / 解密实现
$data = '测试对称加密';
$key = '加密用的 key';
$algorithm = 'DES-EDE-CFB';
$ivlen = openssl_cipher_iv_length($algorithm);
$iv = openssl_random_pseudo_bytes($ivlen);
$password = openssl_encrypt($data, $algorithm, $key, 0, $iv);
echo $password, PHP_EOL;
// 4PvOc75QkIJ184/RULdOTeO8
echo openssl_decrypt($password, $algorithm, $key, 0, $iv), PHP_EOL;
// 测试对称加密
// Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended
openssl_encrypt() 就是加密数据,它须要原文、算法和密钥三个参数,前面的参数是可选的,然而当初是举荐本人来定义 iv(向量)参数,所以如果没有 iv 参数的话,会报一个正告信息。咱们应用 openssl_cipher_iv_length() 来获取以后算法须要的 iv 长度,而后应用 openssl_random_pseudo_bytes() 函数来生成一个随机的合乎算法长度的 iv 内容。
两头那个 0 的参数是指定标记的按位或值,它有两个可选常量:OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING,如果设置为 OPENSSL_RAW_DATA 加密后的数据将依照原样返回(二进制乱码内容),如果设置为 OPENSSL_ZERO_PADDING,加密后的数据将返回为 base64 之后的内容。
openssl_decrypt() 用于对数据进行解密,须要的参数根本和加密函数统一,只是原文数据换成了加密数据。
在对称加密中,咱们还有一种 AEAD 明码模式(GCM 或 CCM),在应用这种模式的算法时,咱们须要多一参数。
$algorithm = 'aes-128-gcm';
$password = openssl_encrypt($data, $algorithm, $key, 0, $iv, $tags);
echo $password, PHP_EOL;
// dPYsR+sdP56rQ99CNxciah+N
echo openssl_decrypt($password, $algorithm, $key, 0, $iv, $tags), PHP_EOL;
// 测试对称加密
这个 $tags 是一个援用类型的参数,也就是加密后会赋值到这个变量中,解密的时候也须要雷同的这个验证标签。
从加密解密的过程来看,如果咱们要将这些信息保留在数据库中,或者进行传输解密时,咱们至多要保留或传输这几个字段,加密应用的 iv,加密应用的算法,以及 AEAD 模式的话加密所应用的验证标签,否则数据无奈解密。
对称加密算法查问
print_r(openssl_get_cipher_methods());
// Array
// (// [0] => AES-128-CBC
// [1] => AES-128-CBC-HMAC-SHA1
// [2] => AES-128-CFB
// [3] => AES-128-CFB1
// [4] => AES-128-CFB8
// [5] => AES-128-CTR
// [6] => AES-128-ECB
// [7] => AES-128-OFB
// [8] => AES-128-XTS
// [9] => AES-192-CBC
// [10] => AES-192-CFB
// [11] => AES-192-CFB1
// [12] => AES-192-CFB8
// ……
// )
在下面加 / 解密测试中所选取的算法就是从这个函数中找进去的,这个函数就是显示以后环境下所有反对的算法列表。
总结
这篇文章的内容有比拟多的实践相干的常识,大家还是要多多地消化。应用 OpenSSL 实现加 / 解密的性能其实还是比较简单的,毕竟货色都曾经帮咱们封装好了,咱们只须要依照文档来调用函数就能够了。学习,还是要实践结合实际,当然,更重要的是本人多入手!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84OpenSSL%E5%8A%A0%E5%AF%86%E6%89%A9%E5%B1%95%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%B8%80%EF%BC%89%EF%BC%9A%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86.php
参考文档:
https://www.php.net/manual/zh/function.openssl-encrypt.php
https://www.php.net/manual/zh/function.openssl-decrypt.php
各自媒体平台均可搜寻【硬核项目经理】