PHP下使用openssl扩展进行对称加密解密的方法
在实际的项目开发中,为了保证数据的安全性,我们一般都要对数据进行加密,一般的加密方式有以下几种
1、使用discuz中,贡献的authcode来进行加密,解密,用了很长一段时间,很简单,使用方便,自己做一个工具包,每次包含进来就可以了,
2、使用mcrypt扩展,然后可以选择对应的数据加密方式进行加密
3、使用openssl扩展进行加密或者解密。
先说第一种,使用discuz带的authcode进行加密,解密,非常的简单,方便,本地使用很好,但是有个问题,如果是和外部程序做对接的时候就会比较麻烦,因为加密算法和其他语言不通用,尤其,比如如果我们要写和银行这些对接的接口,那么这个时候,就需一些通用的加密算法,各种语言都识别的,这个时候,就到了我们需要选择具体加密算法的时候了。
如何选择指定的加密算法进行加密解密呢,这个时候,我们就需要使用外部扩展,
第一个扩展是mcrypt 用了比较久,但是可惜,从php7.2开始被抛弃了,
第二个就是 openssl扩展,那么,我们就用openssl 来进行 对称加密的处理
第一个,我们要知道,我们能使用的加密,解密方法有哪些,
这个时候,我们使用函数 openssl_get_cipher_methods()
就可以获取到,目前我们支持的 加密解密方法有哪些
<?php$method = openssl_get_cipher_methods();print_r($method);然后,我们可以看到非常多的加密方法,
程序运行结果的部分截图
然后,我们对于对称加密,首选AES加密,
那么,我们需要确认一个加密方法,我喜欢加密级别高点的,那么就有
256位的加密,
比如我们可以选择 aes-256-cbc 或者 aes-256-ecb 等,有个简单的概念就是AES的加密方式,是基于数据块的加密方式,对于ECB和CBC的区别呢,
ECB 就是明文内容被分割成长度等长的块,然后分开加密,最后输出组合成密文
CBC呢,是循环型的,每一个分组的加密都和前面一组的内容有关,所以相对来说说,破解难度会增加,但是因为,CBC中,每个内容块,都需要和前面一个分段产生依赖关系,就产生了一个问题,就是,第一个分组 前面是没有内容的,那怎么办呢,就引入了IV的概念,也就是初始化向量,实际上IV的作用主要是给CBC加密方式下 第一组数据前面增加一个可以依赖的数据。所以对于CBC加密模式下,我们就需要提交一个IV参数
好,我们具体的来说下,如何加密解密,我们首先使用aes-256-ecb 这个是没有IV参数的,所以呢,我们看2个函数
openssl_encrypt($orgData,$method,$key,$option,$iv) 加密openssl_decrypt($encrypData,$method,$key,$option,$iv) 解密我们一般就是用4个参数,注意中间有个$key 就是混淆字符串。
然后,基本的实现代码是
<?php$method = aes-256-ecb;$source = "abc";$key = "secret string";首先3个基本的参数 分别对应
$method 加密方法
$source 源字符串
$key 混淆字符串,正式的产品中,请设置的足够复杂
$method = aes-256-ecb;$source = "abc";$key = "secret string";$encrypData = openssl_encrypt($source,$method,$key,0,);//加密,注意这里的$option 我默认设置的是0 因为我使用的是ecb,所以$iv 也是空的。//这样就返回了加密后的字符串,$orgData = openssl_decrypt($encrypData,$method,$key,0,);//解密,除了第一个参数外,其他的必须和前面加密的一样,否则不能解密好,前面,我们使用的是ecb模式,
如果我们要使用cbc模式,更强的加密方式的话,就需要提供$iv了,
那么,如果需要$iv 我们首先要知道 对应加密算法的$iv的长度是多少,利用函数
$ivlen = openssl_cipher_iv_length($method); //只有cbc模式下,才会有长度,其他的都是0获取长度后,我们可以利用函数 生成一个对应长度的$iv
$iv = openssl_random_pseudo_bytes($ivlen); //一定要注意,需要有一个前面的长度获取,然后组合起来就是
$method = aes-256-cbc;$source = "abc";$key = "secret string";//多一个$iv的获取过程$ivlen = openssl_cipher_iv_length($method);$iv = openssl_random_pseudo_bytes($ivlen);$encrypData = openssl_encrypt($source,$method,$key,0,$iv);//加密,需要传递对应的$iv$orgData = openssl_decrypt($encrypData,$method,$key,0,$iv);//解密,同样需要一个$iv这样子,我们就完成了一个统一的加密,解密方式,
唯一注意下,就是关于第4个参数 的简单说明
0 : 自动对明文进行 padding, 返回的数据经过 base64 编码.1 : OPENSSL_RAW_DATA, 自动对明文进行 padding, 但返回的结果未经过 base64 编码.2 : OPENSSL_ZERO_PADDING, 自动对明文进行 0 填充, 返回的结果经过 base64 编码.所以,我们这里使用0 默认返回的就是 base64的编码方式,可以用于存储和传递
本文系作者 @河马 原创发布在河马博客站点。未经许可,禁止转载。
暂无评论数据