php怎么实现数据库字段加密_php如何用AES透明加密敏感列数据

云杰酱_2568

云杰酱_2568

2026-03-22

474人浏览

原创

PHP用openssl_encrypt加密必须正确设置模式和填充,默认PKCS#7填充最安全;密钥需严格16或32字节,IV须随机生成并存储;MySQL字段应选VARBINARY存二进制密文,避免字符集转换。

php怎么实现数据库字段加密_php如何用aes透明加密敏感列数据

PHP 用 openssl_encrypt 加密字段前必须设对模式和填充

直接调 openssl_encrypt 却解不出,八成是 OPENSSL_ZERO_PADDING 或 OPENSSL_PKCS1_PADDING 搞错了。AES 是分组加密,PHP 默认用 PKCS#7 填充(openssl_encrypt 内部自动处理),但如果你手动用了 OPENSSL_ZERO_PADDING,就得自己补零、对齐 16 字节,否则解密失败或乱码。

常见错误现象:openssl_decrypt 返回 false,或解出乱码但长度刚好是 16 的倍数。

  • 生产环境一律用 OPENSSL_ENCRYPT + OPENSSL_ZERO_PADDING 配合手动填充——不推荐,容易出错
  • 默认就用 OPENSSL_ENCRYPT(不用显式传 padding 参数),让 PHP 自动处理 PKCS#7
  • 密钥长度必须严格:AES-128 要 16 字节,AES-256 要 32 字节;用 hash('sha256', $key, true) 安全截取,别用 substr 截字符串
  • IV 必须每次加密随机生成,且和密文一起存(比如拼在密文前,或另存一列),不能复用、不能硬编码

MySQL 里存 AES 加密数据,字段类型选 VARBINARY 不是 VARCHAR

加密后的二进制数据不是 UTF-8 文本,用 VARCHAR 存会触发字符集转换(比如从 utf8mb4 转成 latin1),再读出来就废了。哪怕你 Base64 编码后存字符串,也得确认连接字符集和字段校对规则不干扰 —— 最省心是存原生二进制。

使用场景:用户身份证号、手机号、银行卡号等敏感列,要求落库即密文,应用层透明加解密。

  • 字段类型必须是 VARBINARY(255)(AES-256-CBC 下,100 字符原文加密后约 136 字节,留点余量)
  • 如果非要存 Base64 字符串,字段用 VARCHAR(344)(136×2 四舍五入),并确保 PDO 连接时加 ;charset=binary 或显式设 PDO::ATTR_EMULATE_PREPARES => false
  • 不要用 MySQL 自带的 AES_ENCRYPT() —— 密钥管理难、无法跨语言、且 8.0.30+ 已标记为 deprecated

解密失败时先查 openssl_error_string(),不是重写逻辑

PHP 的 OpenSSL 扩展报错极其安静,openssl_decrypt 失败只返回 false,不抛异常。你改十遍 IV 生成方式,不如花 10 秒看下 OpenSSL 底层到底卡在哪。

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载

性能影响:每次加解密都调 openssl_error_string() 有开销,但开发期必须开;上线后可关,靠日志捕获 false 后再临时启用排查。

  • 在解密后立刻加:if ($decrypted === false) { error_log('OpenSSL error: ' . openssl_error_string()); }
  • 典型错误:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt → IV 或密钥错、或密文被截断/损坏
  • error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length → 填充方式不匹配,比如加密用默认 PKCS#7,解密却传了 OPENSSL_ZERO_PADDING

Laravel Eloquent 中透明加密列,别碰 casts 里的 encrypted

Laravel 9+ 内置的 encrypted cast 看似方便,但它用的是 OpenSSL + base64 + 固定 IV(其实是用 key 衍生的),密钥轮换困难,且不支持自定义 IV 存储位置。一旦数据库迁移或服务拆分,基本没法平滑过渡。

真实使用场景:老项目要快速给几个字段加密,又不想大改 ORM 层。

  • 自己写一个 EncryptedCast 类,实现 get/set,把 IV 存进同一行另一列(如 phone_iv),密文存 phone_enc
  • 避免在 set 里直接调 parent::set,否则会触发两次序列化;原始值应走 $model->attributes['phone_enc'] = $ciphertext
  • 不要在模型事件(如 saving)里统一加密 —— 查询时不会自动解,还得额外加访问器,容易漏

最麻烦的从来不是加密本身,而是密钥怎么安全注入、IV 怎么跟密文原子写入、以及——当某天要换密钥重加密全表时,那段跑在凌晨三点的 migration 脚本,有没有加锁和断点续传。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

12544

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

7221

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2235

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

4548

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

5274

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

4151

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

5997

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

4702

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

12482

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习