php - PHP RSA加密openssl问题
问题描述
我一直在绞尽脑汁。我正在使用最新版本的 php 7。我可以让 rsa 处理短文本,但是长文本似乎不起作用。我读到使用openssl_seal/open ..当我在测试页面上演示代码时效果很好..当我用mysql将它付诸实践时,它没有按预期的方式工作..
加密代码:
$messageiv = openssl_random_pseudo_bytes(32);
openssl_seal($_POST[$_SESSION['message']], $encryptedmessage, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);
openssl_seal($_POST[$_SESSION['subject']], $encryptedsubject, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);
然后将上面的内容进行 base91_encoded 并存储到 blobs/varchar 中。
解密它
openssl_open(base91_decode($row['messagesubject']), $decryptedsubject, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));
openssl_open(base91_decode($row['messagebody']), $decryptedbody, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));
上述变量 $decryptedsubject 和 $decryptedmessage 为空。
在使用 openssl_public/private 密钥加密/解密并添加填充之前,我遇到了这个问题,这有效,但是对于长文本,它不会加密/解密......
任何帮助都会很棒...
解决方案
我可以让 rsa 处理短文本,但是长文本似乎不起作用。
这是意料之中的。RSA 仅在短输入上运行。如果要使用 RSA 加密长消息,则需要执行以下两项操作之一:
- 将您的消息分成几个不同的块并分别加密。这是缓慢、低效和不安全的。(攻击者可以丢弃或重新排序块。)
- 使用结合 RSA 和 AES 的安全结构,就像这样。
因此,你最终会得到这样的结果:
- 加密
- 生成一个随机的 32 字节密钥,
k
. k
使用您的 RSA 公钥加密以获得C
.- 计算 HMAC-SHA256(
C
,k
) 得到消息密钥m
。 - 使用 AES-256-GCM加密您的消息 (
P
)m
以获取D
. - 返回
C
和D
。
- 生成一个随机的 32 字节密钥,
- 解密
- 生成一个随机的虚拟密钥,我们称之为
k'
. C
使用您的 RSA 私钥解密,以获得k
(一次性 AES 密钥)。- 如果第 2 步失败,请使用恒定时间算法换
k
出k'
. - 计算 HMAC-SHA256(
C
,k
) 得到消息密钥m
。 - 解密
D
使用m
. - 返回解密后的明文(或由于身份验证标签而失败)。
- 生成一个随机的虚拟密钥,我们称之为
我读到使用openssl_seal/open ..当我在测试页面上演示代码时效果很好..当我用mysql将它付诸实践时,它没有按预期的方式工作..
首先,考虑改用 libsodium。
无论您是否继续使用 OpenSSL,您都可能希望对您的输出进行 base64 编码(并确保将数据存储在文本字段中而不是短 varchar 中)。
推荐阅读
- json - 在 React 中保持数据更新
- tfs - VS 2019 及旧版本的 TFS
- delphi - 离线时需要给定用户的 Active Directory 组列表
- sql-server - 使用 Powershell SQL Server 模块高效检索表
- javascript - 通过 GET 请求使用上一页的数据加载模板页面?
- dart - (颤振)在网格视图生成器中选择对项目的影响
- .net - 如何在.net核心的startup.cs中获取主机名
- visual-studio-2017 - VS 2019 Ctrl + ,不像 VS 2017
- python - 你如何使用一个类来调用不同的类?
- ansible - 如何将多行字符串复制到带有文字换行符的文件中?