php加密解密的用法(对称加密,非对称加密)

加密和摘要的区别
***摘要:是从已知的数据中,通过摘要计算出一个值,一个数据对应一个或多个摘要的值 ***
比如:md5 和 sha1 sha256 hash 就是得到一个特定的值 ,同一个数据得到的md5 是一样的,不会改变的
比如:password_hash 产生的是一个可以变化的摘要,同一个数据每一次生成的都是不一样的结果,当验证的时候可以使用password_verify 来验证是否正确
以下是上面的使用代码

 		$str = "hello huangjunhui";
        var_dump(md5($str));
        echo "<br/>";
        var_dump(hash("md5",$str));
        echo "<br/>";
        var_dump(sha1($str));
        echo "<br/>";
        var_dump(hash("sha1",$str));
        echo "<br/>";
        var_dump(hash("sha256",$str));
        echo "<br/>";
        var_dump(hash("sha512",$str));
        echo "<br/>";

在这里插入图片描述
这里说一下 hash 的用法, hash($algo,$data);
algo是散列的算法, 如果想要查看 hash 可以支持哪些算法, 可以使用 hash_algos() 函数, 得到的数组就是 hash 支持的算法


以上的摘要都是唯一值的, 同样还有一种算法不是唯一值的,比如我们使用的 password_hash 函数

   $str = "hello huangjunhui";
        $result = password_hash($str,PASSWORD_DEFAULT);
        //得到加密的结果
        echo $result."<br/>";  //$2y$10$4sFjS28dGe/DM5MQMQKPp.R.wWWqZYgHJQCHqGjo8vfPPKYrrBzl2
                                //$2y$10$uPBE9MKkJh1r4NSk5VgzduUhrgeMLgnJXzmbghEdh8cK3swnvAXEm
        echo (int)password_verify($str,$result); //这里是一个布尔值,强转了int

在这里插入图片描述
上面可以看到, 每一次 password_hash的结果都是不一样的, 当验证的时候, 却总是结果为 真,所以这种方法,一般都用在存储用户的密码到数据库,就算数据库丢失,也不会让用户的密码泄漏
上面的几个摘要方法有一个共同点就是 不可逆,也就是说,你想通过密文再获取到原文是不可能的, 所以以上的算法都属于摘要算法


加密解密

能加密解密,就是说,我不仅可以从原文得到密文,也可以从密文在反过来得到原文
主要有两种方式, 一种是对称加密, 一种是非对称加密

php 的加解密用的 openssl_encrypt 和 openssl_decrype
顺便说一句, php之前有一个加密的方法 mcrypt 方法过时了

openssl 的使用注意事项

我在 windows 系统中使用的 openssl , 首先要在 php.ini中打开 openssl的扩展,同时还要找到openssl 的 配置文件(openssl.cnf)的路径,在会使用的时候要指明 openssl.cnf 的路径, 不然会报错
在这里插入图片描述
可以看到,phpinfo中的 openssl 的配置件在 /usr/local/ssl/openssl.cnf 路径中,window 中根本没有这个路径,所以我们在使用 php 的 openssl的时候要在配置中指明配置文件的路径

对称加密,就是加解密过程中,所使用的密钥是一样的

对称加密的算法, 通常有 AES 和 DES 两中,下面我们来看看 PHP 中的对称加密
对称加密通常用于内部的系统, 比如本地的文件加密, 加密时会产生一上 iv向量, 在进行网络传输时, 是要和密文一起传给接收方的, 双方密主要保证 密钥的安全, 不泄漏就可以了
以下是 生成一个密文, 再解密这个密文的代码

//生成一个密文,并返回 密文和iv向量    
public function openssl(){
        $str = "hello world,huang junhui";   //待加密的字符串
        $key = openssl_random_pseudo_bytes(16);  //这里相当于就是一个密钥了, 加密和解密时的密码必须是一样的才可以
        dump(strlen($key)); //int(16)
        $keybase64 = base64_encode($key);    //因为上一步生成的 key是一个 二进制的数据, 显示出来是乱码, 所在要想显示,就要base64一下$key1 = base64_decode($keybase64);
        dump($keybase64);
        dump(strlen($keybase64)); //int(24)
        $cipher = "AES-128-CBC";  //这里是加密算法的名称  可以使用  openssl_get_cipher_methods() 查看所有支持的加密算法名称
        $ivLen = openssl_cipher_iv_length($cipher);     //获取算法对应初始化向量的长度
        $iv = openssl_random_pseudo_bytes($ivLen);  //随机生成一个初始化向量  //这里也可以手写一个长度为 $ivLen 的字符串,此例中$ivLen是16, 所以可以随便写一个 ”sfasfasdfsdfasdf“
        $encrypted = openssl_encrypt($str,$cipher,$key,OPENSSL_RAW_DATA,$iv);
        //$encrypted = openssl_encrypt($str,$cipher,$keybase64,OPENSSL_RAW_DATA,"sfasfasdfsdfasdf");  //字符长度必需是16位的 $ivLen的长度
        //这里使用 $key 和 $keybase64 不影响效果(长度不一样 一个是16一个是24), 也就是说 密钥的长度是可以任意长度的, 只要加密和解密的时侯使用同一个 key就可以了
        //由于对称加密的特殊性, 当传输数据的时候,是要把iv明文一起传输线接收方的,所以当我们返回给请求方的时候要把 密文加上 $iv 一起传送给前端,又因为$iv是一个二进制数据,所以要base64一下,才可以在网络中传输
        // dump(base64_encode($encrypted.":".$iv));
        //接收端接到数据之后,首先base64_decode ,然后使用 ":" 把密文和向量数据分开

        return base64_encode($encrypted.":::".$iv);
        //$decrypted = openssl_decrypt($encrypted,$cipher,$key,OPENSSL_RAW_DATA,$iv);
        //$decrypted = openssl_decrypt($encrypted,$cipher,$keybase64,OPENSSL_RAW_DATA,"sfasfasdfsdfasdf");
        //dump($decrypted);

    }

//解密密文
    public function decodeopenssl(){
        //传入的加密结果 "PDwc77SaX/WcpipdClDx3dYCQBjwWarDswmcwkYKUYU6OjqwKjMwKxcMKU34FYTRhqoj"
        //加密时使用的 key "XHvcRREJw5vlJKP8AoR39A=="
        //$base64str = input("secret_content");
        $str = base64_decode("PDwc77SaX/WcpipdClDx3dYCQBjwWarDswmcwkYKUYU6OjqwKjMwKxcMKU34FYTRhqoj");
        dump($str);
        $secretArr = explode(":::",$str);
        $secretbody = $secretArr[0];
        $iv = $secretArr[1];
        $key = base64_decode("XHvcRREJw5vlJKP8AoR39A==");
        $cipher = "AES-128-CBC";
        $decrypted = openssl_decrypt($secretbody,$cipher,$key,OPENSSL_RAW_DATA,$iv);
        dump($decrypted);
    }

对称加密,是双方都知道密钥的情况下,使用的,最主要的是密钥的安全,iv 明文传输没关系

非对称加密

非对称加密可以用作对数据的加密, 也可以用作对数据的签名;
加密和签名的理解, 加密的时候是 返回给接收方一段无序的数据, 要对方解密才可以使用,签名是, 把原数据给接收方,并在返回的数据中 带上一个由原数据生成的一个签名数据

    public function openssl(){
        $str = "hello world,huang junhui";   //待加密的字符串
        //上面说过,在windows中,openssl 的配置文件的路径是要自己找定的  系统默认的路径不是正确的,所以我们要进 配置文的的路径的配置
        //两种方式, 一种是在系统环境变量中配置  环境变量名:OPENSSL_CONF     变量值 :就是openssl.cnf文件的位置  D:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf
        //另一种方式,在config数组中配置 "config" =>"D:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf" , 注意config 的结构
        $config = [
            "config"=>"D:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf",
            "digest_alg" => "sha512",           //摘要算法或签名的算法  非必填
            "private_key_bits" => 2048,         //私钥的长度  512  1024  2048  4096 通常选1024或2048
            "private_key_type" => OPENSSL_KEYTYPE_RSA,      //加密类型  通常可以选择OPENSSL_KEYTYPE_DSA、 OPENSSL_KEYTYPE_DH、 OPENSSL_KEYTYPE_RSA 或 OPENSSL_KEYTYPE_EC。 默认值是 OPENSSL_KEYTYPE_RSA。
        ];
        //创建私钥和公钥资源
        $res = openssl_pkey_new($config);     //注意这里是一个包含了公私钥的资源
        //资源中获取私钥      公私钥资源      生成的私钥       第三个参数是可以加一些盐值   第四个参数是 上面的配置项
        openssl_pkey_export($res, $private_key, null, $config);
        //dump($private_key);
        //从资源中获取公钥数组信息
        $public_key_arr = openssl_pkey_get_details($res);
        $public_key = $public_key_arr["key"];
        dump($public_key);
        //这样我们就生成了一对公私钥, 我们可以把每个生成的公私钥保存到数据库,得到一个数据库的编号,然后把公钥数据传给请求方,请求方使用公钥加密数据之后, 再返回给服务器, 服务器使用私钥解密

        //签名 //签名是用公钥签名,使用私钥来验证签名
        openssl_sign($str,$sign,$private_key,OPENSSL_ALGO_SHA1);
        dump(openssl_verify($str,$sign,$public_key,OPENSSL_ALGO_SHA1));

        //有了上面的公钥,我们就可以用来加密、
        openssl_public_encrypt($str,$encrypted_data,$public_key);
        dump($encrypted_data);
        //解密数据
        openssl_private_decrypt($encrypted_data,$decrypted_data,$private_key);
        dump($decrypted_data);
    }

以上就是openssl 的用法


下面是一个 封装的 RSA 类 , 可以做参考

<?php
 
 
/**
 * RSA签名类
 */
class Rsa
{
    public $publicKey = '';
    public $privateKey = '';
    private $_privKey;
 
    /**
     * * private key
     */
    private $_pubKey;
 
    /**
     * * public key
     */
    private $_keyPath;
 
    /**
     * * the keys saving path
     */
 
    /**
     * * the construtor,the param $path is the keys saving path
     * @param string $publicKey  公钥
     * @param string $privateKey 私钥
     */
    public function __construct($publicKey = null, $privateKey = null)
    {
 
        $this->setKey($publicKey, $privateKey);
    }
 
    /**
     * 设置公钥和私钥
     * @param string $publicKey  公钥
     * @param string $privateKey 私钥
     */
    public function setKey($publicKey = null, $privateKey = null)
    {
        if (!is_null($publicKey)) {
            $this->publicKey = $publicKey;
        }
        if (!is_null($privateKey)) {
            $this->privateKey = $privateKey;
        }
    }
 
    /**
     * * setup the private key
     */
    private function setupPrivKey()
    {
        if (is_resource($this->_privKey)) {
            return true;
        }
        $pem = chunk_split($this->privateKey, 64, "\n");
        $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
 
        $this->_privKey = openssl_pkey_get_private($pem);
        return true;
    }
 
    /**
     * * setup the public key
     */
    private function setupPubKey()
    {
        if (is_resource($this->_pubKey)) {
            return true;
        }
        $pem = chunk_split($this->publicKey, 64, "\n");
        $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
        $this->_pubKey = openssl_pkey_get_public($pem);
        return true;
    }
 
    /**
     * * encrypt with the private key
     */
    public function privEncrypt($data)
    {
        if (!is_string($data)) {
            return null;
        }
        $this->setupPrivKey();
 
        $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }
 
    /**
     * * decrypt with the private key
     */
    public function privDecrypt($encrypted)
    {
        if (!is_string($encrypted)) {
            return null;
        }
        $this->setupPrivKey();
        $encrypted = base64_decode($encrypted);
        $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }
 
    /**
     * * encrypt with public key
     */
    public function pubEncrypt($data)
    {
        if (!is_string($data)) {
            return null;
        }
        $this->setupPubKey();
        $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
        if ($r) {
            return base64_encode($encrypted);
        }
        return null;
    }
 
    /**
     * * decrypt with the public key
     */
    public function pubDecrypt($crypted)
    {
        if (!is_string($crypted)) {
            return null;
        }
        $this->setupPubKey();
        $crypted = base64_decode($crypted);
        $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
        if ($r) {
            return $decrypted;
        }
        return null;
    }
 
    /**
     * 构造签名
     * @param string $dataString 被签名数据
     * @return string
     */
    public function sign($dataString)
    {
        $this->setupPrivKey();
        $signature = false;
        openssl_sign($dataString, $signature, $this->_privKey);
        return base64_encode($signature);
    }
 
    /**
     * 验证签名
     * @param string $dataString 被签名数据
     * @param string $signString 已经签名的字符串
     * @return number 1签名正确 0签名错误
     */
    public function verify($dataString, $signString)
    {
        $this->setupPubKey();
        $signature = base64_decode($signString);
        $flg = openssl_verify($dataString, $signature, $this->_pubKey);
        return $flg;
    }
 
    public function __destruct()
    {
        is_resource($this->_privKey) && @openssl_free_key($this->_privKey);
        is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey);
    }
}
$publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKZ1mKTymRoGKnHiP1xAy4aiyt5r0BscCZnDAonCrMFZ4kBGriPNHxEaLr5lfBnMKw7k6i+2dsFPSEZooTvqtPUCAwEAAQ==';
$privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApnWYpPKZGgYqceI/XEDLhqLK3mvQGxwJmcMCicKswVniQEauI80fERouvmV8GcwrDuTqL7Z2wU9IRmihO+q09QIDAQABAkBunx3nGHXYjppsfn++7iyTd+I7+Agfy/0xWyB3rpEiGGgfemjcRFaeq5SC2vUNXsrEOY5gbUSQmFxH//Cym18NAiEA1z1cZx/Q9cbIjFPwp1a+K5CVFDXDcfbi/AQgAkVs0/cCIQDF+2fr23AoBslcOC4S0yAx94AbgxCntYuRqztxybsrcwIgMW86ZcT87TX2oaQ1xXk6vC68zqN6fBZEE7Wu1Fa1pAkCIElmOJP3qfAc/AAlj+dIwLHlqWgJwl3674CU9Bfui2bDAiEA0CKJpF8x7KANCcopEQC93PsbIztuML322LOfDV1Lw/k=';
$rsa=new Rsa($publicKey,$privateKey);
$str="abc";
echo "原始数据:".$str;
echo "<br/><hr>";
$res=$rsa->privEncrypt($str);
echo "私钥加密数据:".$res;
echo "<br/>";
 
$res2=$rsa->pubDecrypt($res);
echo "公钥解密数据:".$res2;
echo "<br/><hr>";
 
 
$res3=$rsa->pubEncrypt($str);
echo "公钥加密数据:".$res3;
echo "<br/>";
 
$res4=$rsa->privDecrypt($res3);
echo "私钥解密数据:".$res4;
echo "<br/><hr>";
 
echo "签名数据:".$str;
$res5=$rsa->sign($str);
echo "<br/>";
echo "签名结果:".$res5;
$res6=$rsa->verify($str,$res5);
echo "<br/>";
echo "验证签结果:".$res6;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/120983.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python自动化测试(十一):写入、读取、修改Excel表格的数据

目录 一、写入 1.1 安装 xlwt 1.2 增加sheet页 1.2.1 新建sheet页 1.2.2 sheet页写入数据 1.2.3 excel保存 1.2.4 完整代码 1.2.5 同一坐标&#xff0c;重复写入 二、读取 2.1 安装读取模块 2.2 读取sheet页 2.2.1 序号读取shee页 2.2.2 通过sheet页的名称读取she…

实用知识(工作中常用)

mybatis-plus联表查询 pom.xml坐标 <!-- mybatis-plus-join --> <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join</artifactId><version>1.2.4</version> </dependency>使用步骤&…

【可视化Java GUI程序设计教程】第5章 Swing容器的使用

Swing采用自顶向下的方式构建GUI&#xff0c;即先创建容器&#xff0c;再向容器中添加组件。 “组件”面板中的Swing容器 5.1 面板容器&#xff08;JPanel&#xff09; 5.5.1 使用方法 创建面板有以下两种方法 &#xff08;1&#xff09;创建一个窗体&#xff08;JFrame&…

SAP BASIS SET_PARAMETER_ID_TOO_LONG

ji 原因 DATA:curvbelnid(40) TYPE c,"问题在这里curposnrid(40) TYPE c. "问题在这里curvbelnid sy-uname && VN.curposnrid sy-uname && PR.SET PARAMETER ID curvbelnid FIELD i_vbeln . SET PARAMETER ID curposnrid FIELD i_posnr . 改成 D…

ci-cd的流程

1、项目在gitlab上&#xff0c;从gitlab上使用git插件获取源码&#xff0c;构建成war包&#xff0c;所以使用tomcat作为运行环境 发布 &#xff1a;使用maven插件发布&#xff0c;使用ssh连接。

【Android】画面卡顿优化列表流畅度一

卡顿渲染耗时如图&#xff1a; 卡顿表现有如下几个方面&#xff1a; 网络图片渲染耗时大上下滑动反应慢&#xff0c;甚至画面不动新增一页数据加载渲染时耗时比较大&#xff0c;上下滑动几乎没有反应&#xff0c;画面停止没有交互响应 背景 实际上这套数据加载逻辑已经运行…

支持向量机 (SVM):初学者指南

照片由 Unsplash上的 vackground.com提供 一、说明 SVM&#xff08;支持向量机&#xff09;简单而优雅用于分类和回归的监督机器学习方法。该算法试图找到一个超平面&#xff0c;将数据分为不同的类&#xff0c;并具有尽可能最大的边距。本篇我们将介绍如果最大边距不存在的时候…

Failed to connect to github.com port 443:connection timed out

解决办法&#xff1a; 步骤1&#xff1a; 在这里插入图片描述 步骤2&#xff1a; -步骤3 &#xff1a;在git终端中执行如下命令&#xff1a; git config --global http.proxy http:ip:port git config --global https.proxy http:ip:port git config --global http.proxy htt…

重磅发布 OpenAI 推出用户自定义版 ChatGPT

文章目录 重磅发布 OpenAI 推出用户自定义版 ChatGPT个人简介 重磅发布 OpenAI 推出用户自定义版 ChatGPT OpenAI 首届开发者大会 (OpenAI DevDay) 于北京时间 11 月 7 日凌晨 02:00 开始&#xff0c;大会上宣布了一系列平台更新。其中一个重要更新是用户可以创建他们自己的自定…

智慧农业:农林牧数据可视化监控平台

数字农业是一种现代农业方式&#xff0c;它将信息作为农业生产的重要元素&#xff0c;并利用现代信息技术进行农业生产过程的实时可视化、数字化设计和信息化管理。能将信息技术与农业生产的各个环节有机融合&#xff0c;对于改造传统农业和改变农业生产方式具有重要意义。 图扑…

SysML理论知识

概述 由来 长期以来系统工程师使用的建模语言、工具和技术种类很多&#xff0c;如行为图、IDEF0、N2图等&#xff0c;这些建模方法使用的符号和语义不同&#xff0c;彼此之间不能互操作和重用。系统工程正是由于缺乏一种强壮的标准的建模语言&#xff0c;从而限制系统工程师和…

Makefile 介绍

目录 一、Makefile 的规则 二、一个示例 三、make 是如何工作的 四、makefile 中使用变量 五、让 make 自动推导 六、另类风格的 makefile 七、清空目标文件的规则 make 命令执行时&#xff0c;需要一个 Makefile 文件&#xff0c;以告诉 make 命令需要怎么样的去编译和…

用Python实现朴素贝叶斯垃圾邮箱分类

一、实验目的 通过本实验&#xff0c;旨在使用朴素贝叶斯算法实现垃圾邮箱分类&#xff0c;并能够理解并掌握以下内容&#xff1a; 了解朴素贝叶斯算法的基本原理和应用场景。 学习如何对文本数据进行预处理&#xff0c;包括去除标点符号、转换为小写字母、分词等操作。 理解特…

git 生成公钥

1、通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen -t ed25519 -C "Gitee SSH Key" 三次回车 2、查看生成的 SSH 公钥和私钥&#xff1a; ls ~/.ssh/ 3、把公钥设置到git id_ed25519.pub 4、测试 ssh -T gitgitee.com 成功&#xff01;&#xff01;&…

Hive3 on Spark3配置

1、软件环境 1.1 大数据组件环境 大数据组件版本Hive3.1.2Sparkspark-3.0.0-bin-hadoop3.2 1.2 操作系统环境 OS版本MacOSMonterey 12.1Linux - CentOS7.6 2、大数据组件搭建 2.1 Hive环境搭建 1&#xff09;Hive on Spark说明 Hive引擎包括&#xff1a;默认 mr、spark、…

从vue源码中看diff算法

一、v-for必须要指定key&#xff0c;其作用是什么&#xff1f; 在源码中有一个函数为&#xff0c;其中就是通过判断两个vnode的type和key进行判断&#xff0c;如果这两个属性相同&#xff0c;那么这两个vnode就是相同&#xff0c;所以在设置key的时候也不可以设置为object等无…

Fortigate SSL VPN路径遍历漏洞(CVE-2018-13379)

Fortigate SSL VPN路径遍历漏洞&#xff08;CVE-2018-13379&#xff09; 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: body"FortiToken clock drift detected" 漏洞复现1. 访问链接查看是否存在漏洞2. 查看用户名密码3. 登录后台 免责声明 仅用于技术交流,目的是…

Spring Cloud - 手写 Gateway 源码,实现自定义局部 FilterFactory

目录 一、FilterFactory 分析 1.1、前置知识 1.2、分析源码 1.2.1、整体分析 1.2.2、源码分析 1.3、手写源码 1.3.1、基础框架 1.3.2、实现自定义局部过滤器 1.3.3、加参数的自定义局部过滤器器 一、FilterFactory 分析 1.1、前置知识 前面的学习我们知道&#xff0c…

OpenAI开源全新解码器,极大提升Stable Diffusion性能

在11月7日OpenAI的首届开发者大会上&#xff0c;除了推出一系列重磅产品之外&#xff0c;还开源了两款产品&#xff0c;全新解码器Consistency Decoder&#xff08;一致性解码器&#xff09;和最新语音识别模型Whisper v3。 据悉&#xff0c;Consistency Decoder可以替代Stabl…

CROS错误 403 preflight 预检

预检 403 响应 Response for preflight 403 forbidden 如上图&#xff0c;配置了请求接口一直报错&#xff0c;前端看了没有什么问题&#xff0c;不知道哪里报错了&#xff0c;那么可能是后端没有设置跨域。&#xff08;或者是设置了&#xff0c;但是可能需要换一种方式&#…