openssl_crypt 中初始化向量的使用

2024-05-10

我看了一下this https://stackoverflow.com/questions/1391132/two-way-encryption-in-php问题,并想为自己做。当我运行这段代码时(直接取自这个答案 https://stackoverflow.com/a/6639179/962144):

$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, '1234567812345678');

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);

//Result
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";

但是我收到警告

openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended

所以我去看了docs http://www.php.net/manual/en/function.openssl-encrypt.php,但“没有文档”。我找到了这个comment http://www.php.net/manual/en/function.openssl-encrypt.php#99188,但仍然没有提到初始化向量应该是什么以及我应该如何使用它。谁能启发我吗?

我知道我可以做更多的谷歌搜索,但 Stackoverflow 在如此多的搜索结果中排在第一位,我认为这个问题可能对其他遇到这个问题的人有用。


IV 通常是一个随机数,用于保证加密文本的唯一性。

为了解释为什么需要它,让我们假设我们有一个用“secret”密钥加密的人名数据库,没有使用 IV。

1 John dsfa9p8y098hasdf
2 Paul po43pokdfgpo3k4y
3 John dsfa9p8y098hasdf

如果约翰 1 知道他的密文 (dsfa9p8y098hasdf) 并且可以访问其他密文,他可以轻松找到其他名为约翰的人。

现在实际上,需要 IV 的加密模式将始终使用 IV。如果您不指定 IV,它会自动设置为一堆空字节。想象一下第一个例子,但 IV 为常数 (00000000)。

1 John dsfa9p8y098hasdf 00000000
2 Paul po43pokdfgpo3k4y 00000000
3 John dsfa9p8y098hasdf 00000000

为了防止重复的密文,我们可以使用相同的“秘密”密钥和随机 IV 来加密名称:

1 John sdf875n90mh28458 86714561
2 Paul fg9087n5b60987nf 13541814
3 John gjhn0m89456vnler 44189122

正如您所看到的,两个“John”密文现在不同了。每个 IV 都是独一无二的,并且会影响加密过程,从而使最终结果也独一无二。 John 1 现在不知道用户 3 的名字是什么。

当然,解密需要使用与加密文本相同的 IV,这就是为什么它必须与加密数据一起存储的原因。对于解密来说,如果没有密钥,IV 是无用的,因此与加密文本一起传输或存储它是无关紧要的。

这是一个过于简单的例子,但事实是,不使用 IV 会产生严重的安全后果,这就是 IV 存在的首要原因。毫无疑问,无数的无 IV 加密实现已被利用。

随着我的安全知识的进步,我了解到各种分组密码模式和串联技术(与下面描述的串联方法没有特别相关)有一些更复杂的利用,可以利用 IV 来获取密钥。著名的利用例子RC4 https://en.wikipedia.org/wiki/RC4数据流来确定密钥并解密旧技术的 Wi-Fi 流量,例如WEP https://en.wikipedia.org/wiki/Wired_Equivalent_Privacy and WPA https://en.wikipedia.org/wiki/Wi-Fi_Protected_Access:

  • 密钥调度算法的弱点 RC4 https://www.cs.cornell.edu/people/egs/615/rc4_ksaproc.pdf
  • 对固定 RC4 的实际攻击 无线加密协议模式 https://iacr.org/archive/asiacrypt2005/390/390.pdf

现在,您的代码似乎正在设置 IV (1234567812345678),但在解密时没有使用它。那是肯定会失败的。

您可能还想利用 PHP 的一些 IV 生成函数。我认为这应该对你有用:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, 0, $iv);
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash, 0, $iv);

对于存储/传输,一种选择是简单地连接 IV 和密文,如下所示:

$data = $iv.$encryptedMessage;

然后在检索时,拉出 IV 进行解密:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = substr($data, 0, $iv_size);
$decryptedMessage = openssl_decrypt(substr($data, $iv_size), $encryptionMethod, $secretHash, 0, $iv);

例如,如果您将 IV 存储在数据库中,您还可以将 IV 存储在相邻列中以简化提取过程。


有关更多信息,请查看 PHP 的 Mcrypt 库。它功能非常齐全,并且有大量示例,其中许多示例可以帮助您实现 openssh 加密。http://php.net/manual/en/function.mcrypt-encrypt.php http://php.net/manual/en/function.mcrypt-encrypt.php


强制性安全免责声明:我的话以最简单的方式描述了最简单的概念。就我的知识广度和深度而言,我绝对是一个新手。即使是最优秀的安全研究人员和专家也会引入加密漏洞每时每刻。即便如此,你自己写的越少,你的用户、客户、家人和朋友就会越好。没有冒犯的意思!虽然学习加密理论很有趣,很有趣,甚至很实用,尤其是在像 PHP 这样易于访问的计算机科学中应用,但保持最新的最佳实践并使用最新的可信库将为 99.9999999 提供最安全的系统% 我们。没有什么是完美的,但最好是站在巨人的肩膀上。正如一位智者可能会说的:“你越learn你越意识到自己是多么的渺小know."

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openssl_crypt 中初始化向量的使用 的相关文章

  • 如何显示 PHP 对象

    我有这样的代码 dataRecord1 client gt GetRecord token table filter echo pre print r dataRecord1 echo pre foreach dataRecord1 gt
  • SQLSTATE[HY000] [2002] 资源暂时不可用 - mysql - innodb 和 pdo

    在我的错误日志中得到大量结果 如下所列 数据库中的所有表都是 innodb 并且就与这些表的任何交互而言 一切都是带有准备好的语句的 pdo 正如我所说 所有错误几乎与下面列出的错误相同 但发生在几个不同的页面上 无论页面如何 错误行始终指
  • 将字符串的第一个字母大写(前面带有特殊字符) - PHP

    我想将字符串大写 例如 hello 我希望我的函数返回 Hello 我尝试过使用 regex 和 preg match 但没有运气 这是我之前的问题 与此相关 preg match 正在匹配两个字符 而它应该只匹配一个字符 https st
  • php 中 php.ini 的 log_errors 和 error_log

    我正在尝试通过 php ini 更改 php ini 中的设置 我的问题是 当出现错误时 它不会放入文件 error log txt 中 那么我做错了什么 这是我的代码 Settings for php ini ini set sessio
  • 提交简单 PHP 表单时出现禁止错误

    我有一个不复杂的问题 这似乎比应有的更复杂 我有一个简单的表单 用于向网站添加内容 有些字段需要输入html 然而 当您在表单的不同部分输入某些 html 元素时 它会认为它讨厌您并抛出禁止的 403 错误 这是下面的表格
  • PHP FTP_PUT 上传到目录

    我正在自学PHP 一本名为 PHP完全参考 PHP5 2 的书 我目前正在使用第 11 章 FTP 上传 删除 makedir 等 但遇到了一些本书未涵盖的问题 根据我的教科书 这是上传到服务器的简单代码 connect ftp conne
  • 如何接收发送到 twilio 号码的短信

    我在 twilio 创建了一个免费帐户 用于通过我的网站发送短信 注册后 我得到了一个 twilio 号码 例如 XXX XXX XXXX 我可以向手机号码发送消息 但我不知道如何使用这个 twilio 号码接收短信 请帮我解决这个问题 T
  • 如何在PHP中完成http响应并进行进一步处理?

    就我而言 我需要向客户端回显一个标志并发送一封电子邮件 现在客户端需要等待电子邮件发送 但我想把这两个步骤分开 该怎么做呢 你可以看一下异步运行 PHP 任务 https stackoverflow com questions 858883
  • 如何读取密钥文件以与 HMAC_Init_ex() 一起使用

    我使用 openssl 生成了 RSA 私钥 我需要使用纯 C 语言中的 OpenSSL 库的 HMAC 函数来对数据进行哈希 签名 但我不确定如何从该文件中正确提取私钥数据 据我所知 该文件是 B64 编码的 因此我将其取消编码并将其存储
  • FPM 与 apache2 无法工作(权限被拒绝)

    我正在尝试使用 apache fastcgi 和 fpm 设置一个 Debian Web 服务器 但我越来越恼火 一旦我停用 mod php 我就会收到以下错误 2014 年 5 月 22 日星期四 12 16 10 错误 客户端 xxx
  • 如何使用 PATCH 更新简单的数据库字段?

    我是 php 和 API 的新手 我正在尝试学习这些方法 但我无法执行 PATCH 或 PUT 来更新我的简单 mysql 数据库 我使用了以下代码 if isset PATCH con mysqli connect localhost r
  • zend框架验证模型中的数据而不是表单中的数据

    使用 Zend Framework 2 在我的应用程序中 要编辑数据库中的数据 可以编译 html 表单或发送 http post 请求 我的服务器作为 Web 服务实现 在第二种情况下 不会呈现表单 问题 如果当服务器收到不是从表单发送而
  • Google Drive V3、Google API 客户端 2.0 - 批量上传失败

    使用 Google Drive V3 和 API v2 0 主分支进行批量上传失败 我已经修改了https github com google google api php client blob master examples batch
  • 安全地评估简单的数学

    我想知道是否有一种安全的方法来评估数学 例如 2 2 10000 12000 10000 20 2 2 40 20 23 12 无需使用eval 因为输入可以来自任何用户 我需要实现的只是整数的加法和减法 是否有任何已经存在的代码片段 或者
  • 什么是 PHP session_start()

    它是否基于 cookie 启动当前会话 从 PHP 网站上得到的 PHP如何控制会话 如果我在用户打开我的登录页面时启动会话 我什至可以使用该会话做什么 我可以使用当前会话来获取有关登录用户的信息吗 PHP 会话系统允许您将数据安全地存储在
  • MVC 框架中的缓存策略?

    我编写了自己的小型 PHP MVC 框架 现在正在探索 PHP MVC 框架中的缓存策略 我正在考虑可以缓存什么 在哪里以及如何缓存 我的框架是简单的MVC框架 我有前端控制器 它启动应用程序 注册类自动加载 设置 php 运行时指令 最后
  • 如何让php页面从html页面接收ajax post

    我有一个非常简单的表单 其中有一个名字输入字段 我捕获了表单数据 并使用标准 jQuery 发布方法通过 ajax 将其传输到 PHP 页面 但是 我根本无法从 PHP 页面获得任何在服务器端捕获数据的响应 我不确定我做错了什么或缺少什么
  • 如何在没有 SSH 和 CLI 访问生产的情况下部署 symfony 项目 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 大多数托管提供商仅具有 FTP 访问权限 是否可以 常见地进行 symfony 项目 3 x 或 4 x 的本地安装 然后通过 FTP 上
  • Yii2 无效调用:设置只读属性

    我有一个Post具有多对多关系的模型Tags 在 Post 模型中定义 public function getTags return this gt hasMany Tags className id gt tag id gt viaTab
  • 突出显示单词并提取其附近文本的函数

    我有一个文本例如 Etiam porta semmalesuada magna mollis euismod 整数取数 ante venenatis dapibus posuere velit aliquet 埃蒂亚姆 门塔 塞姆 male

随机推荐

  • 使用 Boost program_options 指定级别(例如 --verbose)

    我的一些选择有多个级别 例如的 冗长 我希望我的用户在以下两种等效样式之间进行选择 no argument verbosity of 1 my program v count the v s verbosity of 4 my progra
  • 在 Eclipse 中突出显示修改的行

    在 netbeans 中 如果我打开一个受版本控制的文件 则修改的行会在左侧突出显示 绿色表示新行 蓝色表示修改行 在Eclipse中是否可以得到类似的效果 打开首选项窗口 搜索 差异 选择快速差异 将 使用此参考源 更改为 SCM 提供程
  • 双向 SSL 说明

    我对双向 SSL 的工作原理有些困惑 客户端如何创建其证书以发送到服务器 是从服务器生成并分发给客户端吗 另外 双向 SSL 相对于单向 SSL 有何优势 两个证书在连接之前都应该存在 它们通常由证书颁发机构创建 不一定相同 在其他情况下
  • Mailchimp 自动化多次发送同一封电子邮件

    我在登陆页面上使用 mailchaimp 自动化工作流程向我的客户发送电子邮件 自动化工作流程是 客户在我的表格中输入他的电子邮件 使用 api V3 将客户添加到我的 mailchimp 列表 或更新 如果已存在 我使用此触发器调用发送第
  • 如何在公共 Maven/Ivy 存储库中搜索特定类?

    有一些网站 例如http mvnrepository com http mvnrepository com 让我搜索 工件 并给出定义 我可以将其添加到我的项目中 以便从公共存储库自动下载库 但是这个特定的例子 mvnrepository
  • java套接字/输出流写入:它们会阻塞吗?

    如果我只写入输出流上的套接字 它会阻塞吗 只有读取才能阻塞 对吗 有人告诉我写入可以阻塞 但我只看到套接字读取方法的超时功能 Socket setSoTimeout 对我来说 写入可能会阻塞是没有意义的 如果我只写入输出流上的套接字 它会阻
  • 从 spinner sqlite 加载文本和值

    我有一个微调器将数据加载到 sqlite 我在数据库中有字段 ID 和字段名称 private void loadSpinnerDataHama database handler DatabaseSpinner db new Databas
  • 无法使用 python 在 aws cdk 中编写策略文档

    您好 我正在开发 AWS CDK 我正在努力制定政策 下面是我的代码 MWSECSServiceRole iam Role self MWSECSServiceRole assumed by iam ServicePrincipal ecs
  • 尝试 .Split 时出现“列必须与键长度相同”错误

    下面的代码在 Python 3 8 10 中运行良好 但在 Python 3 10 中无法运行 知道可能是什么问题吗 import pandas as pd import requests url https coinmarketcap c
  • 如何在node.js中使用混合C++和.Net dll? (错误:已调用 abort())

    我想在 Visual Studio 2015 中使用包含 C 和 C 代码的 dll 创建本机节点扩展 我无法使其工作如下我自己的指示 https stackoverflow com q 11257690 709537去年的 这是基于最新的
  • pdf文件文本阅读和搜索

    我想从 pdf 文件中读取文本并将文本搜索到 pdf 文件中 这是我知道的链接 这些都帮不了我 使用 Quartz 2D 解析 pdf 时获取文本位置 https stackoverflow com questions 3627745 ge
  • 变量如何存储在堆栈中?

    我读到有两个内存区域 一个是堆栈 另一个是堆 基本数据类型 如 int double float 等 存储在堆栈中 而引用类型存储在堆中 我们知道堆栈是LIFO这意味着最后推送的元素将首先被删除 现在假设以下代码 int first 10
  • 使用 VB.Net 的 GhostText

    大家好 我尝试创建一个幽灵文字在文本框上使用标签 我使用的是VB Net2005 我用这段代码完成了这个 Public Class frmDataEntry Private Sub PhantomTextLastName If txtLas
  • (PLSQL) 在 Oracle 更新触发器中测试更改值的最简单表达式是什么?

    这是一个可以解决问题的布尔表达式 nvl new location old location new location is null old location is null 但我想有一个更简单的表达方式 有任何想法吗 这些较短的方法都有
  • 删除 DB 但不删除 *.mdf / *.ldf

    我正在尝试自动化分离和删除数据库的过程 通过 VBS objshell run 如果我手动使用 SSMS 分离和删除我可以将数据库文件复制到另一个位置 但是如果我使用 sqlcmd U sa P MyPassword S local Q A
  • Angular 2 Bootstrap 模态

    我正在尝试将 Bootstrap Modal 对话框包装在 Angular 2 组件 指令 虽然运气不太好 我看过https github com shlomiassaf angular2 modal https github com sh
  • POST 请求在 Postman 中有效,但在 Python 请求中无效(带有机器人检测的 200 响应)

    我有一个 POST 请求 可以与 Postman 和 cURL 完美配合 它返回 JSON blob 数据 然而 当我使用 Python 的 Requests 库执行完全相同的请求时 我得到了 200 成功响应 但我得到的不是 JSON b
  • Vuejs - 如何使用 v-for 获取数组中的所有唯一值(删除重复项)

    如何只显示一个按钮distinct date 我可以使用两个 v for 循环吗 如何选择distinct我的循环中的值 div div
  • gdb 中的 是什么意思?

    gdb n 134 a b c 0xdeadbeef uint32 t length initval gdb n gdb p a 30
  • openssl_crypt 中初始化向量的使用

    我看了一下this https stackoverflow com questions 1391132 two way encryption in php问题 并想为自己做 当我运行这段代码时 直接取自这个答案 https stackove