PHP的openssl加密扩展使用小结(推荐)


Posted in PHP onJuly 18, 2016

引言

互联网的发展史上,安全性一直是开发者们相当重视的一个主题,为了实现数据传输安全,我们需要保证:数据来源(非伪造请求)、数据完整性(没有被人修改过)、数据私密性(密文,无法直接读取)等。虽然现在已经有SSL/TLS协议实现的HTTPS协议,但是因在客户端上依赖浏览器的正确实现,而且效率又很低,所以一般的敏感数据(如交易支付信息等)还是需要我们使用加密方法来手动加密。

虽然对于一般的WEB开发人员来说,大可不必深入了解一些安全相关的底层技术,但学习加密基础知识,使用现有加密相关工具却十分必要。由于工作需要,自己看了些加密相关文章,结合自己的使用经历,完成此文。

加密基础

学习如何使用加密之前,我们需要了解一些加密相关的基础知识。

加密算法一般分为两种:对称加密算法和非对称加密算法。

对称加密

对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密,获取信息。常见的对称加密算法有: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()来获取,我们选取其中一个使用,$method列表形如:

Array(
  0 => aes-128-cbc,  // aes加密
  1 => des-ecb,    // des加密
  2 => des-ede3,   // 3des加密
  ...
  )

其解密函数为 string openssl_encrypt ( string $data , string $method , string $password)

非对称加密相关:

openssl_get_publickey();openssl_pkey_get_public();   // 从证书导出公匙;
openssl_get_privatekey();openssl_pkey_get_private();  // 从证书导出私匙;

它们都只需要传入证书文件(一般是.pem文件);

openssl_public_encrypt(string $data , string &$crypted , mixed $key [, int $padding = OPENSSL\_PKCS1\_PADDING ] )

使用公匙加密数据,其中$data是要加密的数据;$crypted是一个引用变量,加密后的数据会被放入这个变量中;$key是要传入的公匙数据;由于被加密数据分组时,有可能不会正好为加密位数bit的整数倍,所以需要$padding(填充补齐),$padding的可选项有 OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING,分别为PKCS1填充,或不使用填充;

与此方法相对的还有(传入参数一致):

openssl_private_encrypt(); // 使用私匙加密;
openssl_private_decrypt(); // 使用私匙解密;
openssl_private_decrypt(); // 使用公匙解密;

还有签名和验签函数:

bool openssl_sign ( string $data , string &$signature , mixed $priv_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )
int openssl_verify ( string $data , string $signature , mixed $pub_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )

签名函数:$data为要签名的数据;$signature为签名结果的引用变量;$priv_key_id为签名所使用的私匙;$signature_alg为签名要使用的算法,其算法列表可以使用openssl_get_md_methods ()得到,形如:

array(
  0 => MD5,
  1 => SHA1,
  2 => SHA256,
  ...
)

验签函数:与签名函数相对,只不过它要传入与私匙对应的公匙;其结果为签名验证结果,1为成功,0为失败,-1则表示错误;

加密实例

以下是一个非对称加密使用的小例子:

// 获取公匙
$pub_key = openssl_get_publickey('test.pem');

$encrypted = '';
// 对数据分块加密
for ($offset = 0, $length = strlen($raw_msg); $offset < $length; $offset += $key_size){  
  $encryptedBlock = '';
  $data = substr($raw_msg, $offset, $key_size)
  if (!openssl_public_encrypt($data, $encryptedBlock, $pub_key, OPENSSL_PKCS1_PADDING)){
    return '';
  } else {
    $encrypted .= $encryptedBlock;
 }
 return $encrypted;

而对称加密就非常简单了,直接使用ssl_encrypt()函数即可;

当然一些接口可能会对加密方法进行不同的要求,如不同的padding,加密块大小等等,这些就需要使用者自己调整了。

因为我们是在HTTP协议之上处理的数据,所以数据加密完成后,就可以直接发送了,不用再考虑底层的传输,使用cURL或SOAP扩展方法,就可以直接请求接口啦。

结语

密码学是一个十分高深的学科,它理论艰深,概念繁多,作为一个WEB开发人员,虽然不需要我们去研究其底层实现,但是学会使用封装好的方法很有利于我们开发。甚至了解其基本实现,也可以触类旁通,对算法等有新的理解。

以上这篇PHP的openssl加密扩展使用小结(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PhpMyAdmin出现export.php Missing parameter: what /export_type错误解决方法
Aug 09 PHP
destoon会员注册提示“数据校验失败(2)”解决方法
Jun 21 PHP
PHP处理JSON字符串key缺少双引号的解决方法
Sep 16 PHP
使用phpstorm和xdebug实现远程调试的方法
Dec 29 PHP
php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证
May 04 PHP
CI框架数据库查询之join用法分析
May 18 PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
Jun 13 PHP
PHP7匿名类用法分析
Sep 26 PHP
thinkPHP5.0框架应用请求生命周期分析
Mar 25 PHP
PHP 多任务秒级定时器的实现方法
May 13 PHP
PHP配置ZendOpcache插件加速
Feb 14 PHP
PHP使用ActiveMQ实现消息队列的方法详解
May 31 PHP
PHP多进程编程总结(推荐)
Jul 18 #PHP
php 指定范围内多个随机数代码实例
Jul 18 #PHP
php 解决substr()截取中文字符乱码问题
Jul 18 #PHP
Yii2中cookie用法示例分析
Jul 18 #PHP
PHP socket 模拟POST 请求实例代码
Jul 18 #PHP
Yii2简单实现给表单添加验证码的方法
Jul 18 #PHP
yii2缓存Caching基本用法示例
Jul 18 #PHP
You might like
php zip文件解压类代码
2009/12/02 PHP
php的memcached客户端memcached
2011/06/14 PHP
php 操作符与控制结构
2012/03/07 PHP
thinkphp 一个页面使用2次分页的实现方法
2013/07/15 PHP
php+mysqli实现批量执行插入、更新及删除数据的方法
2015/01/29 PHP
解决PHP里大量数据循环时内存耗尽的方法
2015/10/10 PHP
php 如何禁用eval() 函数实例详解
2016/12/01 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
强大的jquery插件jqeuryUI做网页对话框效果!简单
2011/04/14 Javascript
自己使用js/jquery写的一个定制对话框控件
2014/05/02 Javascript
JavaScript让Textarea支持tab按键的方法
2015/06/26 Javascript
javascript实现的简单计时器
2015/07/19 Javascript
jQuery实现图片轮播效果代码
2016/09/27 Javascript
Bootstrap轮播图学习使用
2017/02/10 Javascript
JavaScript瀑布流布局实现代码
2017/05/06 Javascript
写一个移动端惯性滑动&amp;回弹Vue导航栏组件 ly-tab
2018/03/06 Javascript
vue+axios实现文件下载及vue中使用axios的实例
2018/09/21 Javascript
vue+iview 兼容IE11浏览器的实现方法
2019/01/07 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python实现两个dict合并与计算操作示例
2019/07/01 Python
python实现文件的分割与合并
2019/08/29 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
Tensorflow中tf.ConfigProto()的用法详解
2020/02/06 Python
Python单元测试及unittest框架用法实例解析
2020/07/09 Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
2020/08/03 Python
image-set实现Retina屏幕下图片显示详细介绍
2012/12/24 HTML / CSS
AURALog面试题软件测试方面
2013/10/22 面试题
党的群众路线教育实践活动个人对照检查材料(公安)
2014/11/05 职场文书
小学生成绩单评语
2014/12/31 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
寒假致家长的一封信
2015/10/10 职场文书
2016年清明节寄语
2015/12/04 职场文书
婚前协议书怎么写,才具有法律效力呢 ?
2019/06/28 职场文书
游戏开发中如何使用CocosCreator进行音效处理
2021/04/14 Javascript
mysql的数据压缩性能对比详情
2021/11/07 MySQL