每个人都应该已经停止使用PHP Mcrypt扩展程序进行新的工作,并且应该计划将其现有的应用程序关闭,因为libmcrypt在2003年被放弃,并且不被保护。
我认为最好的选择是OpenSSL。近年来热度很高,但我认为对称块加密是一个很好的选择。 (我可能会解释为什么我这么想呢)
PHP中的 openssl_encrypt()和openssl_decrypt()的文档有点缺乏。本文旨在填补一些空白。这是两者的签名。
string openssl_encrypt ( string $data , string $method , string $key \[, int $options = 0 [, string $iv = “” ]] )string openssl_decrypt ( string $data , string $method , string $key \[, int $options = 0 [, string $iv = “” ]] )
我们将始终使用一个初始化向量,结果是$options有很大的不同,所以我们可以简化:
string openssl_encrypt ( string $data , string $method , string $key , int $options, string $iv )string openssl_decrypt ( string $data , string $method , string $password , int $options, string $iv )
其中$opention将是OPENSSL_RAW_DATA
或OPENSSL_ZERO_PADDING
它们还需要为您使用的密码算法准备好密钥。我只使用密钥大小为16字节的AES-128。如果您通过openssl_en/decrypt()
一个密钥(在$ password参数中)长于密码的本质密钥大小,则会将该余数丢弃。如果通过一个短于预期的键,则填充为零,即\x00字节。
所以你需要仔细准备你的钥匙。如果用户提供密码,请使用类似PBKDF2的特殊盐。如果您有输入加密密钥,则可以使用HKDF导出openssl_en/decrypt()
的密钥。
所以让我们再简化一下:
string openssl_encrypt ( string $data , string $method , string $key , int $options, string $iv )string openssl_decrypt ( string $data , string $method , string $key , int $options, string $iv )
如果您正在生成密钥,而不是从用户输入密钥或密码中导出密钥,则应使用从加密安全伪随机数生成器或CSPRNG中提取的随机字节的二进制字符串.(我也许会博客介绍如何在PHP中获取这样的字符串,实际上并不像调用openssl_random_pseudo_bytes()
一样简单。)
初始化向量 $iv
初始化向量$iv
的要求类似于$password
的要求。它应该是与密码块大小相同长度的二进制字符串。过多的字节被丢弃,并且太短的$iv
被填充到零字节的块大小。
初始化向量应该是来自CSPRNG的随机字节的二进制串。不要重复使用IV。
密码规范 $method
$method
允许值由PHP平台上的openssl_get_cipher_methods()
函数列出,并在openssl enc文档中更详细地列出。
我不打算讨论这些的相对优点。我唯一使用的是CBC模式的AES。除了RC5(由RAS获得专利但未被广泛使用)外,OpenSSL提供的所有其他对称块密码都具有64位或更小的块。
我总是使用AES-128,它有一个16字节的键。所以这意味着我会选择“AES-128-CBC”。我想你可以安全地选择’AES-192-CBC’或’AES-256-CBC’,但是我不会被引用到最好的论点。
在任何情况下,$method
都必须是openssl_get_cipher_methods()
返回的字符串之一,您必须使用适当长度的$iv
和$key
才能使用该密码。
编码、填充和OPENSSL_RAW_DATA
与OPENSSL_ZERO_PADDING
在Mcrypt中,加密和解密的输入和输出编码是原始的二进制字符串。 Paintext和ciphertext都是二进制字符串。
在CBC或ECB模式下使用块密码加密之前,Mcrypt会自动将零字节填充添加到明文中,并在解密之后返回零字节填充的明文(即,Mcrypt在解密之后不删除填充)。
注意:以下是错误,请参阅下面My1的注释。选项表示两个标志:将OPENSSL_RAW_DATA位设置为使用二进制字符串,并将其设置为base64。设置OPENSSL_ZERO_PADDING位来进行自己的填充或取消设置,openssl_en/decrypt()做PKCS7填充。
OpenSSL有两种模式:
– $options = OPENSSL_RAW_DATA
– openssl_encrypt()和openssl_decrypt()的输入和输出编码都是二进制字符串,即plaintext和cipertext都是二进制字符串。
– openssl_encrypt()在CBC或ECB模式下使用块密码加密之前,将PKCS7填充添加到明文中。 –
– openssl_decrypt()解密之后剥离填充。
– $ options = OPENSSL_ZERO_PADDING
– openssl_encrypt()的输入编码和openssl_decrypt()的输出编码是原始的二进制字符串,即明文是原始的二进制字符串。
– 输出编码fron openssl_encrypt()和对openssl_decrypt()的输入编码是base64,即密文是base64编码的。
– openssl_encrypt()的输入大小必须是块大小的整数倍,否则返回错误代码。 –
– openssl_encrypt()不添加填充,或者由openssl_decrypt()删除,
可以做任何工作,但我更喜欢OPENSSL_RAW_DATA
。如果我需要密文的特定编码,那我宁愿自己做。而PKCS7
将是我的填充选择,实际上这是我用于Mcrypt的。
总结
已经弄清了这两个功能的所有这些未记录的功能,结果是我打算使用OpenSSL进行对称加密的唯一方法是这样的:
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
$plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
其中:
– $plaintext是任何字符串,任何长度。
– $key是16字节长的二进制字符串形式的加密密钥(因为AES-128的密钥大小为16字节)
– $iv是一个16位字节长的加密安全随机二进制字符串(因为AES具有16个字节的块大小),我将只使用一次
– $ciphertext是一个比$plaintext长1到16个字节之间的二进制字符串(因为PKCS7填充到16字节块大小)
并记住加密密钥必须从输入密钥材料或密码中正确派生或由CSPRNG生成。
结语
记住,如果您需要加密数据,那么您几乎肯定也需要进行身份验证。为此,您可以使用HMAC签名。使用SHA-2算法之一。 还要记住最后签名并进行认证,即HMAC需要覆盖包含加密数据的整个消息
原文:https://coderlife.cn/1624.html
http://www.lilinjian.com/web/2018/01/18/php72-AES.html
Original url: Access
Created at: 2019-04-18 11:31:12
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论