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 相关文章推荐
PHP+ajax 无刷新删除数据
Feb 20 PHP
php快速url重写 更新版[需php 5.30以上]
Apr 20 PHP
php下使用strpos需要注意 === 运算符
Jul 17 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
Jun 14 PHP
解析php 版获取重定向后的地址(代码)
Jun 26 PHP
php中url传递中文字符,特殊危险字符的解决方法
Aug 17 PHP
thinkphp实现发送邮件密码找回功能实例
Dec 01 PHP
PHP中字符安全过滤函数使用小结
Feb 25 PHP
PHP实现通过Luhn算法校验信用卡卡号是否有效
Mar 23 PHP
php链表用法实例分析
Jul 09 PHP
深入浅析安装PhpStorm并激活的步骤详解
Sep 17 PHP
open_basedir restriction in effect. 原因与解决方法
Mar 14 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调用数据库的存贮过程
2006/10/09 PHP
基于PHP创建Cookie数组的详解
2013/07/03 PHP
php生成短网址示例
2014/05/05 PHP
php定界符
2014/06/19 PHP
php+js实现百度地图多点标注的方法
2016/11/30 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
php中请求url的五种方法总结
2017/07/13 PHP
浅谈Laravel模板实体转义带来的坑
2019/10/22 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
奉献给JavaScript初学者的编写开发的七个细节
2011/01/11 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
js实现图片放大和拖拽特效代码分享
2015/09/05 Javascript
javascript设计模式Constructor(构造器)模式
2016/08/19 Javascript
Vue.js之slot深度复制详解
2017/03/10 Javascript
JS实现加载时锁定HTML页面元素的方法
2017/06/24 Javascript
vue 的点击事件获取当前点击的元素方法
2018/09/15 Javascript
Angular刷新当前页面的实现方法
2018/11/21 Javascript
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
node Buffer缓存区常见操作示例
2019/05/04 Javascript
JS如何实现网站中PC端和手机端自动识别并跳转对应的代码
2020/01/08 Javascript
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
python使用循环打印所有三位数水仙花数的实例
2018/11/13 Python
python安装numpy和pandas的方法步骤
2019/05/27 Python
Python性能分析工具Profile使用实例
2019/11/19 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
2020/02/05 Python
Django 解决开发自定义抛出异常的问题
2020/05/21 Python
CSS3中的5个有趣的新技术
2009/04/02 HTML / CSS
The North Face北面美国官网:美国著名户外品牌
2018/09/15 全球购物
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
世界上最伟大的马产品:Equiderma
2020/01/07 全球购物
钳工实习自我鉴定
2013/09/19 职场文书
化工专业个人的求职信范文
2013/11/28 职场文书
诚信考试标语
2014/06/24 职场文书
MySQL Router的安装部署
2021/04/24 MySQL
避坑之 JavaScript 中的toFixed()和正则表达式
2022/04/19 Javascript