paragonie / ciphersweet

Fast, searchable field-level encryption for PHP projects
https://ciphersweet.paragonie.com
Other
439 stars 32 forks source link

Possible bug with `new StringProvider` using base64-encoded key #104

Open E-Mans-Application opened 3 months ago

E-Mans-Application commented 3 months ago

Hi,

I've just experienced a strange behaviour with StringProvider (I'm not sure if it's a bug or not). I have generated key kME8GX8+2nhtfVXyLZkPeHLRfkUO99nbJpjAnbC9bZA= using base64_encode(random_bytes(256 / 8)). I'm trying to use the key to create a StringProvider, but the base64-encoded form is not accepted.

Code:

$provider = new StringProvider("kME8GX8+2nhtfVXyLZkPeHLRfkUO99nbJpjAnbC9bZA=");

This code throws: RangeException: Base64::decode() only expects characters in the correct base64 alphabet in /vendor/paragonie/constant_time_encoding/src/Base64.php:228 Stack trace: #0 /vendor/paragonie/ciphersweet/src/KeyProvider/StringProvider.php(41): ParagonIE\ConstantTime\Base64::decode('kME8GX8+2nhtfVX...') #1 /www/xxx.php(xxx): ParagonIE\CipherSweet\KeyProvider\StringProvider->__construct('kME8GX8+2nhtfVX...')

Using new StringProvider(base64_decode("kME8GX8+2nhtfVXyLZkPeHLRfkUO99nbJpjAnbC9bZA=")) instead works fine.

paragonie-security commented 3 months ago

Change your code in this way:

+ use ParagonIE\ConstantTime\Base64;

// ...
- $provider = new StringProvider("kME8GX8+2nhtfVXyLZkPeHLRfkUO99nbJpjAnbC9bZA=");
+ $provider = new StringProvider(Base64::decode("kME8GX8+2nhtfVXyLZkPeHLRfkUO99nbJpjAnbC9bZA="));

What's happening here is, if your input string is 44 characters, it assumes URL-encoded base64, not the other base64.

PHP's base64_decode() is not constant-time. See https://github.com/paragonie/constant_time_encoding for more.