如何计算Laravel加密方法的最大输出长度?

Chr*_*ris 6 php encryption aes laravel laravel-encryption

建立

鉴于以下内容:

$s = Crypt::encryptString('a');
Run Code Online (Sandbox Code Playgroud)

有可能知道,对于长度为1的字符串,可能的长度范围是$s多少?

上下文

数据库存储 - 需要存储加密值,并且希望设置输入字符串的验证,以便在加密时将最长的输入字符串插入到数据库中而不进行截断.

基本测试

使用以下代码段在本地运行一些非常粗略的测试:

Route::get('/test', function() {
    echo '<table>';
    for ($i=0; $i < 100; $i++) { 
        $s = str_repeat('a', $i);
        $l1 = strlen($s);
        $l2 = strlen(Crypt::encryptString($s));
        echo "<tr><td>$l1</td><td>$l2</td></tr>";
    }
    echo '</table>';
});
Run Code Online (Sandbox Code Playgroud)

我可以看到以下内容,但它在运行之间有所不同,例如,一个'a'字符串的长度为188或192(较长的值似乎介于244和248之间).

所以必须有一个公式.我已经看到output_size = input_size + (16 - (input_size % 16))但没有考虑到方差.

产量

0   192
1   188
2   188
3   192
4   188
5   188
6   188
7   192
8   192
9   188
10  188
11  192
12  192
13  192
14  192
15  192
16  220
17  220
18  216
19  216
20  220
Run Code Online (Sandbox Code Playgroud)

编辑

好吧,所以在与@Luke Joshua Park聊天之后,长度的变化来自laravel加密函数和$iv创建的方式,这是随机字节,可以包含/.

$value加密方法里面也可以包含一个/.

当包含a的值/是JSON编码时,将/转义为\\\/每次添加另外3个字符.

真正的问题-能$iv$value含有比单个"/"呢?

Chr*_*ris 3

请注意,我将向@Luke Joshua Park 提供赏金,因为他让我最接近最终的(最接近的)解决方案,即接下来的解决方案。

(不是)解决方案

答案是,没有具体的答案,并非没有未知数和方差。在撰写本文时,关注此问题的三个人(我自己、Luke 和 bartonjs)对于 100% 准确的解决方案仍然存在一些疑问。

提出问题是为了找出存储加密数据的可靠类型和大小,最好以独立于数据库的方式(我不想指定特定的数据库,因为我想知道并理解如何计算长度,而不管它被坚持的方式)。

然而,即使是最小长度的字符串在最坏的情况下也会变得相当长(其中创建了一个包含许多斜杠的随机 $iv - 不太可能或不可能,这是可能的)。可能有 400 字节长的加密字符串n=1意味着 avarchar永远不会是正确的答案。

那么……应该怎么办?

因此,无论原始字符串的长度如何,将加密数据存储为文本字段而不是 varchar(在 mysql 领域)似乎是最好、最一致和最可靠的。这是一个令人失望的无聊答案,不涉及任何花哨的数学。这不是我愿意接受的答案,但却是最有意义的。

但是,密码呢?

在短暂的愚蠢时刻,我想,但是密码字段呢?这是一个varchar。但当然,这是一个散列值,而不是加密值(当这个想法突然出现在我的脑海中时,我还没有喝足够的咖啡,好吗?)