Wednesday, 20 February 2019

How to calculate the maximum length of the output of the Laravel encyption method?

Setup

Given the following:

$s = Crypt::encryptString('a');

Is is possible to know, for a string of length 1, the possible range of lengths of $s?

Context

Database storage - need to store an encrypted value, and would like to set validation of the input string so the longest length input string, when encrypted, is inserted into the db without truncation.

Basic tests

Running some very crude tests locally, using the following snippet:

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>';
});

I can see the following, but it varies between runs, for example, a string of 'a' will be of length of either 188 or 192 (longer values seem to be between 244 and 248).

So there must be a formula. I have seen output_size = input_size + (16 - (input_size % 16)) but doesn't account for the variance.

Output

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

Edit

Ok, so after chatting with @Luke Joshua Park below, the variance in length comes from the laravel encryption function and the way $iv is created, which is random bytes, which can contain /.

$value inside the encryption method can also contain a /.

When values that contain a / are JSON encoded, the / is escaped to \\\/ adding an additional 3 characters per occurrence.

The real problem - can $iv and $value contain more than a single '/'?



from How to calculate the maximum length of the output of the Laravel encyption method?

No comments:

Post a Comment