-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
use password hash to encrypt private key #18121
Conversation
What are the consequences regarding migration? |
Nothing, we don't change existing keys.
|
protected function generatePasswordHash($password, $cipher) { | ||
$instanceId = $this->config->getSystemValue('instanceid'); | ||
$instanceSecret = $this->config->getSystemValue('secret'); | ||
$salt = hash('sha256', $instanceId + $instanceSecret, true); |
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.
This is a nifty one. Basically this will always return 0
, the +
operator is the wrong one here.
Use please .
as otherwise the salt will always be 5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9
, on every instance.
Going further, it might very much make sense to include the user id as well as another work factor:
$salt = hash('sha256', $uid . $instanceId . $instanceSecret, true);
Note that you should use $uid
as first argument to prevent potential padding problems etc.
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.
Use please
.
as otherwise the salt will always be
Indeed this should have been a .
, good catch. Will fix it and also add the uid.
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.
Hm, adding the uid is not that easy. We also have the "public link share"-key and the recovery-key. For them the uid isn't unique. Multiple admins could have access to the recovery key and the "public link share"-key gets created for whoever login first. Further at this point we have no idea which kind of key gets encrypted. So I would skip the uid for now.
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.
That's acceptable as well. The expectation here is "to make it a little bit harder" and not to offer the best possible security with regards to time-memory trade-off attacks. We can't anyways as the admin could intercept data on it's own.
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.
If we touch the code now then let's do it as good as possible. I had another look and added the uid for all regular users, for system users the uid is just a empty string
public function generateHeader() { | ||
public function generateHeader($keyFormat = 'hash') { | ||
|
||
if (in_array($keyFormat, $this->supportedKeyFormats) === false) { |
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.
When using in_array
please always set the strict
parameter to true.
in_array($keyFormat, $this->supportedKeyFormats, true)
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.
fixed and ready to push once Jenkins finished
Code looks good to me. Basic functionality testing also did not find any bugs. @bantu I'd appreciate your feedback on this one as well. Basically previously the encryption key of an user was only encrypted with the user password which limited the potential key space and also made brute-force attacks way easier than necessary. Using PBKDF2 should be a somewhat better approach. It's not perfect but better than before :-) |
4d00ee0
to
854fd63
Compare
A new inspection was created. |
@LukasReschke Without looking to deep into the code changes and from the point of interacting crypto primitives this is much better and more proper indeed. Please note that you already depend on phpseclib and there is PBKDF2 support in it via the setPassword() method on Crypt objects. https://github.com/phpseclib/phpseclib/blob/2.0/phpseclib/Crypt/Base.php#L536 |
Mhm. Seems like adjusting this for our use-case would require also some more work. Considering that the embedded library also is somewhat widely used and only a fallback for PHP 5.4 I'd keep it as-is. 👍 from my side. |
needs a second reviewer... maybe @nickvergessen or @PVince81 ? Thanks! |
👍 |
use password hash to encrypt private key
use password hash instead of the plain password to encrypt the private key as discussed with @LukasReschke .
What should be tested: