ThinkPHP实现的rsa非对称加密类示例


Posted in PHP onMay 29, 2018

本文实例讲述了ThinkPHP实现的rsa非对称加密类。分享给大家供大家参考,具体如下:

公钥加密后的字符串是一直变化的,但是用私钥解密后的内容仍然是相同的,这是为了加密数据使用的。

私钥加密的字符串是不会变化的,即使暴露在外网上别人截取时如果没有公钥也是看不出来内容的,仅允许给予公钥的第三方来解密并看到内容,实际作用相当于签名功能,如果能拿到未加密的内容,说明一定是信任方的数据,因为有他的签名啊。

其实这种非对称加密技术可以用于单点登录中去,安全级别高,能解密获取到内容应该就是信任方的数据。

<?php
namespace Common\Org;
class RsaCrypt {
 const CERPATH ='../Application/Runtime/Data/server.cer'; //生成证书路径
 const PFXPATH = '../Application/Runtime/Data/server.pfx'; //秘钥文件路径
 const FILEDIR = '../Application/Runtime/Data/';
  /**
  * 生成公钥私钥
  */
  public static function generateCertKey()
  {
  $dn = array('countryName'=>'CN', 'stateOrProvinceName'=>'beijing', 'localityName'=>'beijing','organizationName'=>'clcw',
    'organizationalUnitName'=>'clcw', 'commonName'=>'clcw', 'emailAddress'=>'service@clcw.com.cn');
  $privkeypass = 'secret';  //私钥密码
  $numberOfDays = 365;   //有效时长,单位为天
  //生成证书
  $privkey = openssl_pkey_new();
  $csr = openssl_csr_new($dn, $privkey);
  $sscert = openssl_csr_sign($csr, null, $privkey, $numberOfDays);
  openssl_x509_export_to_file($sscert, self::CERPATH);
  openssl_pkcs12_export_to_file($sscert, self::PFXPATH, $privkey, $privkeypass);
  (file_exists(self::CERPATH)) or die('公钥的文件路径错误');
  (file_exists(self::PFXPATH)) or die('密钥的文件路径错误');
  }
  public static function verifyData($originData, $decryptData)
  {
  $cer_key = file_get_contents(self::$cerpath);
  $cer = openssl_x509_read($cer_key);
  $res = openssl_verify($originData, $decryptData, $cer);
  var_dump($res);
  }
  /**
  * 生成公钥私钥文件
  * @param $appName string 应用名称
  */
  public static function generateKey($appName='')
  {
  $result = ['status'=>0, 'msg'=>''];
  if (!extension_loaded('openssl') ) {
   $result['msg'] = 'php需要openssl支持';
  }
  //创建公钥
  $res = openssl_pkey_new();//array('private_key_bits'=>512) 这一串参数不加,否则只能加密54个长度的字符串
  //提取私钥
  openssl_pkey_export($res, $privatekey);
  //生成公钥
  $public_key = openssl_pkey_get_details($res);
  $publickey = $public_key['key'];
  // $path = self::FILEDIR.$appName;
  try{
   // file_put_contents($path.'_public.pem', $publickey);
   // file_put_contents($path.'_private.pem', $privatekey);
   $result['status'] = 1;
   $result['publickey'] = $publickey;
   $result['privatekey'] = $privatekey;
  }catch(\Exception $e) {
   // throw new \Exception($e->getMessage());
   $result['msg'] = $e->getMessage();
  }
  return $result;
  }
  /**
  * 用私钥加密数据
  * @param $data string 需要加密的字符串(最好不要超过200个字符)
  * @param $appName string 应用名称
  */
  public static function privateEncrypt($data, $appName)
  {
  $result = ['status'=>0, 'msg'=>''];
  $privatekey = C($appName.'.PRIVATE_KEY');
  $myinfo = 'In '.__METHOD__.',privatekey:'.$privatekey."\n";
  file_put_contents('/tmp/shiyf.log', $myinfo, FILE_APPEND);
  //生成resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
  $privatekey = openssl_pkey_get_private($privatekey);
  if (empty($privatekey)) {
   $result['msg'] = '密钥不可用';
  }
  $encryptData = '';
  //用私钥加密
  if (openssl_private_encrypt($data, $encryptData, $privatekey)) {
   $result['msg'] = base64_encode($encryptData);
   $result['status'] = 1;
  } else {
   $result['msg'] = '加密失败!';
  }
  return $result;
  }
  /**
  * 用公钥解密数据
  * @param $data string 需要解密的字符串(最好不要超过200个字符)
  * @param $appName string 应用名称
  */
  public static function publicDecrypt($data, $appName)
  {
  $result = ['status'=>0, 'msg'=>''];
  $data = base64_decode($data);
  $publickey = C($appName.'.PUBLIC_KEY');
  //生成resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
  $publickey = openssl_pkey_get_public($publickey);
  if (empty($publickey)) {
   $result['msg'] = '公钥不可用';
  }
  //解密数据
  $decryptData = '';
  if (openssl_public_decrypt($data, $decryptData, $publickey)) {
   $result['msg'] = $decryptData;
   $result['status'] = 1;
  } else {
   $result['msg'] = '解密失败';
  }
  return $result;
  }
  /**
  * 用公钥加密数据
  * @param $data string 需要加密的字符串(最好不要超过200个字符)
  * @param $appName string 应用名称
  */
  public static function publicEncrypt($data, $publickey)
  {
  $result = ['status'=>0, 'msg'=>''];
  //生成resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_private函数返回false
  $publickey = openssl_pkey_get_public($publickey);
  if (empty($publickey)) {
   $result['msg'] = '公钥不可用';
  }
  $encryptData = '';
  //用私钥加密
  if (openssl_public_encrypt($data, $encryptData, $publickey)) {
   $result['msg'] = base64_encode($encryptData);
   $result['status'] = 1;
  } else {
   $result['msg'] = '加密失败!';
  }
  return $result;
  }
  /**
  * 用私钥加密数据
  * @param $data string 需要解密的字符串(最好不要超过200个字符)
  * @param $appName string 应用名称
  */
  public static function privateDecrypt($data, $appName)
  {
  $result = ['status'=>0, 'msg'=>''];
  $data = base64_decode($data);
  $privatekey = C($appName.'.PRIVATE_KEY');
  //生成resource类型的私钥,如果私钥文件内容被破坏,openssl_pkey_get_public函数返回false
  $privatekey = openssl_pkey_get_private($privatekey);
  if (empty($privatekey)) {
   $result['msg'] = '私钥不可用';
  }
  //解密数据
  $decryptData = '';
  if (openssl_private_decrypt($data, $decryptData, $privatekey)) {
   $result['msg'] = $decryptData;
   $result['status'] = 1;
  } else {
   $result['msg'] = '解密失败';
  }
  return $result;
  }
}
PHP 相关文章推荐
一个php作的文本留言本的例子(四)
Oct 09 PHP
在PWS上安装PHP4.0正式版
Oct 09 PHP
PHP中的MYSQL常用函数(php下操作数据库必备)
Sep 12 PHP
php数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
Oct 31 PHP
基于MySQL分区性能的详细介绍
May 02 PHP
Window 7/XP 安装Apache 2.4与PHP 5.4 的过程详解
Jun 02 PHP
比较strtr, str_replace和preg_replace三个函数的效率
Jun 26 PHP
thinkphp实现图片上传功能分享
Mar 04 PHP
PHP的pcntl多进程用法实例
Mar 19 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
Feb 17 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
如何通过PHP实现Des加密算法代码实例
May 09 PHP
PHP中实现中文字串截取无乱码的解决方法
May 29 #PHP
php实现表单提交上传文件功能
May 28 #PHP
PHP封装的非对称加密RSA算法示例
May 28 #PHP
thinkPHP3.2.3结合Laypage实现的分页功能示例
May 28 #PHP
Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配置方法
May 28 #PHP
PHP测试框架PHPUnit组织测试操作示例
May 28 #PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
May 28 #PHP
You might like
php实现图形显示Ip地址的代码及注释
2014/01/20 PHP
php制作中间带自己定义图片二维码的方法
2014/01/27 PHP
CI框架在CLI下执行占用内存过大问题的解决方法
2014/06/17 PHP
自动更新作用
2006/10/08 Javascript
使用EXT实现无刷新动态调用股票信息
2008/11/01 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
2012/10/12 Javascript
jQuery制作仿腾讯web qq用户体验桌面
2013/08/20 Javascript
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
jQuery功能函数详解
2015/02/01 Javascript
点评js异步加载的4种方式
2015/12/22 Javascript
基于JQuery的购物车添加删除以及结算功能示例
2017/03/08 Javascript
vue时间格式化实例代码
2017/06/13 Javascript
js实现鼠标跟随运动效果
2020/08/02 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
详解小程序缓存插件(mrc)
2018/08/17 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
Vue项目利用axios请求接口下载excel
2020/11/17 Vue.js
JavaScript 中的六种循环方法
2021/01/06 Javascript
[01:34]2016国际邀请赛中国区预选赛IG战队教练采访
2016/06/27 DOTA
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Golang与python线程详解及简单实例
2017/04/27 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
2018/02/03 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
什么是CSS3 HSLA色彩模式?HSLA模拟渐变色条
2016/04/26 HTML / CSS
html5读取本地文件示例代码
2014/04/22 HTML / CSS
春节联欢晚会主持词范文
2014/03/24 职场文书
体育系毕业生求职自荐信
2014/04/16 职场文书
一年级学生评语
2014/04/23 职场文书
实习单位鉴定评语
2014/04/26 职场文书
项目建议书怎么写
2014/05/15 职场文书
2014年护理工作总结范文
2014/11/14 职场文书
2014年宣传思想工作总结
2014/12/10 职场文书
六年级语文下册教学计划
2015/01/22 职场文书
python3操作redis实现List列表实例
2021/08/04 Python
浅谈Vue的computed计算属性
2022/03/21 Vue.js