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中的cookie
Nov 26 PHP
php中如何使对象可以像数组一样进行foreach循环
Aug 09 PHP
PHP自动生成后台导航网址的最佳方法
Aug 27 PHP
php发送post请求函数分享
Mar 06 PHP
采用thinkphp自带方法生成静态html文件详解
Jun 13 PHP
ThinkPHP模板判断输出Empty标签用法详解
Jun 30 PHP
PHP数组排序之sort、asort与ksort用法实例
Sep 08 PHP
php下foreach提示Warning:Invalid argument supplied for foreach()的解决方法
Nov 11 PHP
php中call_user_func函数使用注意事项
Nov 21 PHP
php 输出json及显示json中的中文汉字详解及实例
Nov 09 PHP
php array_reverse 以相反的顺序返回数组实例代码
Apr 11 PHP
php 广告点击统计代码(php+mysql)
Feb 21 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
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
Zero Clipboard js+swf实现的复制功能使用方法
2010/03/07 Javascript
Javascript写入txt和读取txt文件示例
2014/02/12 Javascript
javascript的document.referrer浏览器支持、失效情况总结
2014/07/18 Javascript
JS获取当前网页大小以及屏幕分辨率等
2014/09/05 Javascript
自定义函数实现IE7与IE8不兼容js中trim函数的问题
2015/02/03 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
2016/05/24 Javascript
AngularJS使用$http配置对象方式与服务端交互方法
2018/08/13 Javascript
原生JS实现的跳一跳小游戏完整实例
2019/01/27 Javascript
Vue组件通信中非父子组件传值知识点总结
2019/12/05 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
详解在Vue.js编写更好的v-for循环的6种技巧
2020/04/14 Javascript
Python去掉字符串中空格的方法
2014/03/11 Python
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
Python实现的将文件每一列写入列表功能示例【测试可用】
2018/03/19 Python
Python3.6简单反射操作示例
2018/06/14 Python
python登录WeChat 实现自动回复实例详解
2019/05/28 Python
pandas.read_csv参数详解(小结)
2019/06/21 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
pytorch加载自定义网络权重的实现
2020/01/07 Python
python如何支持并发方法详解
2020/07/25 Python
Python3利用scapy局域网实现自动多线程arp扫描功能
2021/01/21 Python
CSS改变网页中鼠标选中文字背景颜色例子
2014/04/23 HTML / CSS
Adobe Html5 Extension开发初体验图文教程
2017/11/14 HTML / CSS
日本网路线上商品代购服务:转送JAPAN
2016/08/05 全球购物
玩具反斗城西班牙网上商城:ToysRUs西班牙
2017/01/19 全球购物
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
2012/05/30 面试题
环境建设实施方案
2014/03/14 职场文书
捐款活动总结
2014/08/27 职场文书
如何在CocosCreator里画个炫酷的雷达图
2021/04/16 Javascript
Golang 对es的操作实例
2022/04/20 Golang
el-form每行显示两列底部按钮居中效果的实现
2022/08/05 HTML / CSS