【PHP】对称加密算法 AES-256-GCM 代码示例

2023-11-03 03:44

本文主要是介绍【PHP】对称加密算法 AES-256-GCM 代码示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

下面介绍在PHP代码中,如何对数据进行 AES-256-GCM 加密和解密。我们可以使用 openssl 和 sodium 扩展来实现加密,它们都支持 AES-256-GCM 算法,下面将给出两种扩展的代码示例。

环境

PHP 7.3

一、使用openssl扩展

<?phpfunction aes256gcm_encrypt(string $data, string $keygen, string $aad = ''): array
{$cipher = 'aes-256-gcm';$ivLen = openssl_cipher_iv_length($cipher);$iv = random_bytes($ivLen); // 12字节的iv$encrypt = openssl_encrypt($data, $cipher, $keygen, OPENSSL_RAW_DATA, $iv,$tag, $aad);return ['iv'          => base64_encode($iv),'tag'         => base64_encode($tag),'aad'         => base64_encode($aad),'cipher_text' => base64_encode($encrypt),];
}function aes256gcm_decrypt(array $secretData, string $keygen)
{$iv = base64_decode($secretData['iv']);$tag = base64_decode($secretData['tag']);$aad = base64_decode($secretData['aad']);$cipherText = base64_decode($secretData['cipher_text']);$cipher = 'aes-256-gcm';return openssl_decrypt($cipherText, $cipher, $keygen, OPENSSL_RAW_DATA, $iv, $tag, $aad);
}function main()
{// AES-256-GCM需要32字节的密钥$keygen = bin2hex(random_bytes(16));// 加密$data = 'Hello World!';$secretData = aes256gcm_encrypt($data, $keygen, 'foobar');// 解密$plainText = aes256gcm_decrypt($secretData, $keygen);echo "原文:$data\n";echo "密文数据:" . json_encode($secretData) . "\n";echo "解密后:$plainText\n";
}main();

二、使用 sodium 扩展

<?phpfunction aes256gcm_encrypt(string $data, string $keygen, string $aad = ''): array
{$iv = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);$encrypt = sodium_crypto_aead_aes256gcm_encrypt($data, $aad, $iv, $keygen); // 包含密文、tagreturn ['iv'          => sodium_bin2base64($iv, SODIUM_BASE64_VARIANT_ORIGINAL),'aad'         => sodium_bin2base64($aad, SODIUM_BASE64_VARIANT_ORIGINAL),'cipher_text' => sodium_bin2base64($encrypt, SODIUM_BASE64_VARIANT_ORIGINAL),];
}function aes256gcm_decrypt(array $secretData, string $keygen)
{$iv = sodium_base642bin($secretData['iv'], SODIUM_BASE64_VARIANT_ORIGINAL);$aad = sodium_base642bin($secretData['aad'], SODIUM_BASE64_VARIANT_ORIGINAL);$cipherText = sodium_base642bin($secretData['cipher_text'], SODIUM_BASE64_VARIANT_ORIGINAL);return sodium_crypto_aead_aes256gcm_decrypt($cipherText, $aad, $iv, $keygen);
}function main()
{if (!sodium_crypto_aead_aes256gcm_is_available()) {exit('Not support AES-256-GCM');}// 生成AES-256-GCM的密钥$keygen = sodium_crypto_aead_aes256gcm_keygen();// 加密$data = 'Hello World!';$secretData = aes256gcm_encrypt($data, $keygen, 'foobar');// 解密$plainText = aes256gcm_decrypt($secretData, $keygen);echo "原文:$data\n";echo "密文数据:" . json_encode($secretData) . "\n";echo "解密后:$plainText\n";
}main();

AAD参数(Additional Authenticated Data)

在上面的代码示例中,可以看到在加密的时候有一个$aad参数,如果在加密的时候使用了这个参数,那么在解密时也需要使用同样的AAD值才能成功解密。

什么时候会需要用到AAD呢?下面举个例子:
用户Alice在CSDN博客上写了一篇私密文章,CSDN使用 AES-256-GCM 加密了这篇文章,然后存储到了数据库里,AAD的取值是Alice的用户ID。

后续如果Alice去查看这篇文章,CSDN会使用Alice的用户ID(AAD值)去解密,因为解密的AAD值与加密的AAD值相同,所以可以成功解密。

然后有一个黑客Bob,他也向CSDN发出解密这篇文章的请求,CSDN就会使用Bob的用户ID作为AAD去解密这篇文章,但因为AAD值错误,肯定是解密不了的,所以这时候AAD的作用就体现了出来。

参阅

  • https://cloud.google.com/kms/docs/additional-authenticated-data?hl=zh-cn

这篇关于【PHP】对称加密算法 AES-256-GCM 代码示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335353

相关文章

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

mysql查询使用_rowid虚拟列的示例

《mysql查询使用_rowid虚拟列的示例》MySQL中,_rowid是InnoDB虚拟列,用于无主键表的行ID查询,若存在主键或唯一列,则指向其,否则使用隐藏ID(不稳定),推荐使用ROW_NUM... 目录1. 基本查询(适用于没有主键的表)2. 检查表是否支持 _rowid3. 注意事项4. 最佳实