傅令江的光影色彩世界
留住记忆的点滴
  • 首页
  • 文学
    • 诗词鉴赏
    • 美文共读
    • 原创
  • 编程
    • php
    • asp
    • .net
    • VB
    • C/C++
    • 易语言
    • js
    • 其他
    • 逆向
  • 运维
    • windows
    • linux
  • 光影色彩
    • 电影
    • 音乐
  • 科技
    • 互联网
    • 手机
  • 生活
    • 情感
  • 微语
1月82022

在PHP里实现AES的加密解密功能(包括mcrypt版本和openssl版本)

作者:傅令江   发布:2022-1-8 22:31   分类:php   阅读:1892次   评论:0条  

1. 介绍

1.1 介绍

福哥需要在php里使用AES加密解密功能,今天整理出来和大家分享一下。

早期的PHP实现AES借助的是mcrypt扩展,后来在PHP7之后就换成了openssl扩展来实现了。mcrypt版本代码比较复杂且需要自己实现PKCS7补位的逻辑,而openssl版本则默认使用了PKCS7补位不需要自己来编写代码实现了。

2. 通过openssl实现

2.1 安装openssl扩展

需要安装php扩展openssl,具体方法就不提供了,php的扩展的安装方式都一样,php7.1以上的版本支持了openssl模块。

2.2 加密解密对象

加密解密对象,默认 AES-256-CBC 方法。

class AES_Encrypt{
    const BLOCK_SIZE = 32;

    private string $method;

    public function __construct(string $method = null){
        if($method == null){
            $method = "AES-256-CBC";
        }
        $this->method = $method;
    }

    public function pkcs7Pad($str){
        $len = mb_strlen($str, '8bit');
        $c = 16 - ($len % 16);
        $str .= str_repeat(chr($c), $c);

        return $str;
    }

    private function pkcs7Encode($text){
        $text_length = strlen($text);

        $amount_to_pad = AES_Encrypt::BLOCK_SIZE - ($text_length % AES_Encrypt::BLOCK_SIZE);
        if ($amount_to_pad == 0) {
            $amount_to_pad = AES_Encrypt::BLOCK_SIZE;
        }

        $pad_chr = chr($amount_to_pad);
        $tmp = "";
        for ($index = 0; $index < $amount_to_pad; $index++) {
            $tmp .= $pad_chr;
        }

        return $text . $tmp;
    }

    private function pkcs7Decode($text){
        $pad = ord(substr($text, -1));
        if ($pad < 1 || $pad > 32) {
            $pad = 0;
        }

        return substr($text, 0, (strlen($text) - $pad));
    }

    public function encrypt(string $data, string $key, string $iv):string {
        $data = $this->pkcs7Encode($data);
        $encrypted = openssl_encrypt($data, $this->method, $key,OPENSSL_ZERO_PADDING, $iv);

        return $encrypted;
    }

    public function decrypt(string $data, string $key, string $iv):string {
        $decrypted = openssl_decrypt($data, $this->method, $key,OPENSSL_ZERO_PADDING, $iv);
        $data = $this->pkcs7Decode($decrypted);

        return $data;
    }
}



2.3 options

openssl_encrypt和openssl_decrypt的第三个参数是options,它有着很重要的作用,我们来了解一下。

  • 0:默认模式,自动进行 pkcs7 补位,同时自动进行 base64 编码

  • 1:OPENSSL_RAW_DATA,自动进行 pkcs7 补位, 但是不自动进行 base64 编码

  • 2:OPENSSL_ZERO_PADDING,需要自己进行 pkcs7 补位,同时自动进行 base64 编码

3. 通过mcrypt实现

3.1 安装mcrypt扩展

需要安装php扩展mcrypt,具体方法就不提供了,php的扩展的安装方式都一样,php7.1以下的版本支持mcrypt模块。

3.2 加密解密对象

加密解密对象,默认 AES-128-CBC 方法。

class AES_Encrypt{
    const BLOCK_SIZE = 32;

    private $RIJNDAEL;
    private $MODE;

    public function __construct($method = null){
        if($method == null){
            $method = "AES-128-CBC";
        }
        $this->RIJNDAEL = null;
        $this->MODE = null;
        $this->methodArr = explode("-", $method);
        switch($this->methodArr[1]){
            case "128":
                $this->RIJNDAEL = MCRYPT_RIJNDAEL_128;
                break;
            case "192":
                $this->RIJNDAEL = MCRYPT_RIJNDAEL_192;
                break;
            case "256":
                $this->RIJNDAEL = MCRYPT_RIJNDAEL_256;
                break;
        }
        switch($this->methodArr[2]){
            case "CBC":
                $this->MODE = MCRYPT_MODE_CBC;
                break;
            case "CFB":
                $this->MODE = MCRYPT_MODE_CFB;
                break;
            case "ECB":
                $this->MODE = MCRYPT_MODE_ECB;
                break;
            case "NOFB":
                $this->MODE = MCRYPT_MODE_NOFB;
                break;
            case "OFB":
                $this->MODE = MCRYPT_MODE_OFB;
                break;
            case "STREAM":
                $this->MODE = MCRYPT_MODE_STREAM;
                break;
        }
        if($this->RIJNDAEL == null || $this->MODE == null){

            throw new Exception("invalid RIJNDAEL or MODE about '". $method. "'", 2000100);
        }
    }

    public function pkcs7Pad($str){
        $len = mb_strlen($str, '8bit');
        $c = 16 - ($len % 16);
        $str .= str_repeat(chr($c), $c);

        return $str;
    }

    private function pkcs7Encode($text){
        $text_length = strlen($text);

        $amount_to_pad = AES_Encrypt::BLOCK_SIZE - ($text_length % AES_Encrypt::BLOCK_SIZE);
        if ($amount_to_pad == 0) {
            $amount_to_pad = AES_Encrypt::BLOCK_SIZE;
        }

        $pad_chr = chr($amount_to_pad);
        $tmp = "";
        for ($index = 0; $index < $amount_to_pad; $index++) {
            $tmp .= $pad_chr;
        }

        return $text . $tmp;
    }

    private function pkcs7Decode($text){
        $pad = ord(substr($text, -1));
        if ($pad < 1 || $pad > 32) {
            $pad = 0;
        }

        return substr($text, 0, (strlen($text) - $pad));
    }

    public function encrypt($data, $key, $iv){
        $data = $this->pkcs7Encode($data);
        $encrypted = mcrypt_encrypt($this->RIJNDAEL, $key, $data, $this->MODE, $iv);
        $based_encrypted = base64_encode($encrypted);

        return $based_encrypted;
    }

    public function decrypt($data, $key, $iv){
        $data = base64_decode($data);
        $encrypted = mcrypt_decrypt($this->RIJNDAEL, $key, $data, $this->MODE, $iv);
        $encrypted = $this->pkcs7Decode($encrypted);

        return $encrypted;
    }
}



4. 使用

使用AES加密需要原数据、AES私钥、令牌,下面给出一个例子。

注意:在openssl版本里的AES-256-CBC方法对应mcrypt版本里的AES-128-CBC,也是微信公众号服务器接口使用的AES算法的方法

4.1 示例

准备一个字符串,加密后再解密,最后如果和原字符串相同,证明函数工作正常。



$dataOrg = "我是福哥,I like coding!!!";
$AESKey = "rN6LfP9qbILPabc938IixdFds3s5ksIqjcPyYxOPx4v";
$iv = "";

// 初始化
$myAES_Encrypt = new AES_Encrypt();

// 加密字符串
$dataEncrypted = $myAES_Encrypt->encrypt($dataOrg, $AESKey, $iv);

// 解密字符串
$dataDecrypted = $myAES_Encrypt->decrypt($dataEncrypted, $AESKey, $iv);

// 比较
var_dump($dataOrg == $dataDecrypted);


5. 总结

今天给出了两个使用PHP实现AES的加密算法功能的方法,新版本的openssl效率更高、代码更简单,推荐这种方法~~

来源

https://tongfu.net/home/35/blog/512693.html










本文固定链接: https://www.fulingjiang.cn/php/207.html

blogger
该日志由 傅令江 于2022-1-8 22:31 Saturday发表在 php 分类下。
版权所有:《傅令江的光影色彩世界》 → 《在PHP里实现AES的加密解密功能(包括mcrypt版本和openssl版本)》;
除特别标注,本博客所有文章均为原创. 互联分享,尊重版权,转载请以链接形式标明本文地址;
本文标签:
上一篇::apache 实现虚拟目录代理方式
下一篇:Python编译为二进制so可执行文件实例

热门文章

  • 兄弟二周年祭

相关文章

  • PHP下载css中的图片
  • PHP性能之语言性能优化:vld——查看代码opcode的神器
  • php将文件夹打包成zip文件 
  • php实时提交百度Sitemap 实时推送代码
  • php 获取302跳转后的地址
取消回复

发表评论

亲,头像对么?

提交中,请稍候……


木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!


  • 日历

  • 存档

    • 2024年10月(1)
    • 2023年2月(1)
    • 2022年11月(1)
    • 2022年10月(10)
    • 2022年9月(13)
    • 2022年8月(2)
    • 2022年7月(14)
    • 2022年6月(2)
    • 2022年5月(8)
    • 2022年4月(7)
    • 2022年3月(13)
    • 2022年2月(2)
    • 2022年1月(9)
    • 2021年12月(2)
    • 2021年11月(4)
    • 2021年10月(2)
    • 2021年9月(6)
    • 2021年7月(4)
    • 2021年6月(3)
    • 2021年5月(3)
    • 2021年4月(11)
    • 2021年3月(13)
    • 2021年2月(2)
    • 2021年1月(1)
    • 2020年12月(1)
    • 2020年4月(5)
    • 2019年9月(1)
    • 2019年8月(1)
    • 2019年5月(3)
    • 2018年3月(1)
    • 2017年10月(1)
    • 2016年7月(1)
    • 2016年4月(1)
    • 2015年12月(1)
    • 2015年11月(3)
    • 2015年9月(1)
    • 2015年8月(10)
    • 2015年7月(1)
    • 2015年6月(1)
    • 2015年4月(1)
    • 2015年3月(3)
    • 2015年2月(8)
    • 2015年1月(4)
    • 2014年12月(1)
    • 2014年11月(27)
    • 2014年10月(13)
    • 2014年9月(14)
    • 2014年8月(26)
    • 2014年7月(21)
  • 最新评论

    • 令狐江:
      喜欢这首歌是因为可以引起共鸣!
  • 链接

    • 演讲稿网
    • Recollect
    • 演讲稿
    • 祁阳人生活网
    • 我爱演讲稿网
  • 搜索

  • 标签

      函数 自定义方法 SEO 分页 分页函数 分页方法 nginx重新的一些规则
  • 分类

    • 文学(0)
    • 编程(0)
    • 运维(0)
    • 光影色彩(0)
    • 科技(0)
    • 生活(0)
    • 诗词鉴赏(3)
    • 美文共读(1)
    • 原创(10)
    • php(111)
    • asp(1)
    • .net(0)
    • VB(0)
    • C/C++(0)
    • 易语言(0)
    • js(8)
    • 其他(9)
    • 逆向(2)
    • windows(11)
    • linux(121)
    • 电影(0)
    • 音乐(1)
    • 互联网(4)
    • 手机(0)
    • 情感(2)
  • 最新文章热门文章随机文章

    • 兄弟二周年祭
    • openai给的ionCube 解密代码,应该是老版本可以这样
    • WordPress – 5秒盾防CC(PHP通用代码)
    • 我高中最好的朋友今天猝死了-伤心得不行
    • Linux系统中 systemd-journaldCPU占用异常的解决方法
    • SVN Skipped 'xxx' -- Node remains in conflict 错误的解决办法
    • 解决Linux读写nfs共享盘速度慢的问题
    • php 获取302跳转后的地址
    • 让vsftp显示隐藏文件的办法,比如显示 .htaccess
    • 添加自签名https证书到centos系统信任的问题
    • php复制文件,目录不存在就创建
    • PHP实现的AES加密、解密封装类与用法示例
    • php 获取301 302的真实地址
    • 123个黑客必备的Python工具!
    • windows下查看so的函数名
Copyright © 2001-2025 傅令江的光影色彩世界. Powered by www.fulingjiang.cn ICP备案:京ICP备14015190号-5