Php 为什么可以';openssl\u public\u加密处理此明文?

Php 为什么可以';openssl\u public\u加密处理此明文?,php,public-key-encryption,php-openssl,Php,Public Key Encryption,Php Openssl,openssl\u public\u encrypt显然无法处理任意明文 <?php $msg = '{"args":["argxx","argyy"],"data":"xx\nyyy\n","symkey":"0a6e860640413acfe6e4e461a28fab3fad3aff78ef95c962c5e63bef7e2b3439"}'; # If you uncomment this line, the function succeeds. # $msg = 'test';

openssl\u public\u encrypt
显然无法处理任意明文

<?php

$msg = '{"args":["argxx","argyy"],"data":"xx\nyyy\n","symkey":"0a6e860640413acfe6e4e461a28fab3fad3aff78ef95c962c5e63bef7e2b3439"}';

# If you uncomment this line, the function succeeds.
# $msg = 'test';

$pub = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC80g7AA5XexMCiJW3tKr/eeN8Q
EMNfGYG0qiUuLS/dtir7c3c1MmpNzrE8R+xqleOLNVkbbSZqqQ2qUJtPhwbLhQyL
yilRH5WMz9Pabx62v7k+vm81/6Xa9fnIV7DE0DZhMO5vQvBE3+5jkXbfU4yBZRv5
UOty5gqGXXaR6bim4QIDAQAB
-----END PUBLIC KEY-----';


if (openssl_public_encrypt ($msg, $enc, $pub))
{
    print bin2hex ($enc);

    exit (0);
}
else
{
    print "Could not encrypt message.\n";
}
?>

这输出的
无法加密消息。
在Ubuntu PHP 7上


为什么它在这个
$msg
上失败?

如果我们根据经验测试这种情况,我们会看到,超过117字节的所有内容都会失败:

$msg = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm';
上一行总共代表117个字符和117个字节。这在使用您提供的公钥加密时有效

如果我添加另一个字符,
n
,加密将失败:

$msg = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn';
其他unicode字符也是如此。假设我尝试对其进行加密,长度为85个字符,但长度正好为117个字节:

$msg = ' i ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui  u';
这是完全加密的。但如果我再添加一个字节,它就会失败(86个字符,118个字节):

。。如果传递的加密字符超过117个,
openssl\u public\u encrypt()
函数将因设计而失败

斯奈德,克里斯,迈尔,托马斯,索斯韦尔,迈克尔,ISBN 978-1-4302-3318-3

此外,书中还说:

由于RSA价格昂贵,而且从未打算对大量数据进行加密,因此,如果您加密的数据通常超过56个字符,则应计划使用快速高效的对称算法(如AES)对数据进行加密,并使用随机生成的密钥


实际密钥为128字节(1024位),这是一个常见的最小可接受密钥大小。128-11 padding bytes=117个允许加密的数据字节


问题中的公钥是经过编码的,并且有额外的页眉和页脚行,因此长度超过128字节。

它在5.6上也会失败。相关评论:您确定是
$msg
?这适用于其他消息?消息是否比RSA密钥长?因为消息的长度不能大于(size_t)INT_MAX:只是一个小小的补充:使用PHP摘录的选择非常糟糕,它太旧并且没有更新:RC4完全不安全,应该,它,不得在新工作中使用,且不得在新工作中使用三元组。当前选择的对称加密是AES(高级加密标准)。此外,答案没有说明消息长度限制为117字节的原因。@zaph您是对的,我完全忽略了这个事实。因此,我删除了注释引用并添加了其他内容。@zaph我不知道为什么它在PHP中正好是117,但限制的概念来自这里:@Axalix查看我添加的naswer。这个answser只是一些确定数据长度的经验测试,不是为什么。谢谢,但是这个神奇的“11”是什么?它来自哪里?11个字节是填充,最常见的填充方案(),填充至少会给消息添加11个字节。看见摘录:*对于RSA,填充对于其核心功能至关重要。RSA有很多数学结构,这导致了它的弱点。使用正确的填充可以防止这些缺点*
$msg = ' i ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui ♥ ui  uZ';