-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Add Deterministic Encryption Support to Laravel Encrypter #56190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. I don't speak on behalf of Laravel with this feedback, just me personally - I think this use case is quite fringe and doesn't belong in the framework core. It would make a fine package, and people who need this can pull it into their app.
* @throws \Illuminate\Contracts\Encryption\DecryptException | ||
*/ | ||
public function decrypt($payload, $unserialize = true); | ||
public function decrypt(string $payload, bool $unserialize = true): mixed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes to the contracts are major breaking changes, and cannot be accepted on 12.x.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can push it to laravel 13 as new feature
This is a must for encrypting something searchable like All test cases ran successfully. |
Now covering deterministic encryption casting as well |
That is one way to be clear. You can use a hash column commonly known as "blind indexing" alongside the non-deterministic encrypted blob to make fields searchable with the caveat that you won't get any partial searches - more so for I don't think throwing an additional parameter on a function is the best developer experience for something that drastically changes the security footprint of a method. I'm with Graham that this probably doesn't belong in core. |
Thanks for your pull request to Laravel! Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include. If applicable, please consider releasing your code as a package so that the community can still take advantage of your contributions! |
Summary
This PR introduces deterministic encryption functionality to Laravel's encryption system, allowing developers to encrypt data in a way that produces consistent, repeatable results for the same input and key combination.
Motivation
Traditional encryption in Laravel is non-deterministic, meaning the same plaintext encrypted multiple times will produce different ciphertext each time due to random initialization vectors (IVs). While this provides excellent security for most use cases, there are specific scenarios where deterministic encryption is valuable:
Changes
New Parameters
Added an optional parameter to encryption methods:
$deterministic
encrypt($value, $serialize = true, $deterministic = false)
encryptString($value, $deterministic = false)
New Eloquent Casts
Added deterministic encryption casts for Eloquent models:
encrypted:deterministic
encrypted:deterministic,array
encrypted:deterministic,json
encrypted:deterministic,object
encrypted:deterministic,collection
Implementation Details
When
$deterministic = true
:hash('sha256', $data . $key)
instead of random bytesWhen (default):
$deterministic = false
Backward Compatibility
This change is fully backward compatible:
Usage Examples
Security Considerations
Deterministic encryption has inherent trade-offs: Pros:
Cons:
Recommendations:
Testing
Comprehensive test coverage has been added to verify:
Breaking Changes
None. This is a purely additive change that maintains full backward compatibility.