-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
Configurable password hashing algorithm/cost #31234
Changes from all commits
a02c3dd
feafc97
ac10583
99a7f1c
f97d866
3625713
3635c11
ede105f
5577013
3ef1ea1
47f911f
4fad6cf
51ee743
3305765
6d28ef0
ef3dc4c
038bc6a
0ab9cb0
5e537fe
44949ca
15cbf2d
17d4028
e2f429a
af85aeb
8cd5ae2
c0d33a9
0f19d47
622a204
918301c
bb85c20
b18203c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,22 +41,22 @@ public ChangePasswordRequestBuilder username(String username) { | |
return this; | ||
} | ||
|
||
public static char[] validateAndHashPassword(SecureString password) { | ||
public static char[] validateAndHashPassword(SecureString password, Hasher hasher) { | ||
Validation.Error error = Validation.Users.validatePassword(password.getChars()); | ||
if (error != null) { | ||
ValidationException validationException = new ValidationException(); | ||
validationException.addValidationError(error.toString()); | ||
throw validationException; | ||
} | ||
return Hasher.BCRYPT.hash(password); | ||
return hasher.hash(password); | ||
} | ||
|
||
/** | ||
* Sets the password. Note: the char[] passed to this method will be cleared. | ||
*/ | ||
public ChangePasswordRequestBuilder password(char[] password) { | ||
public ChangePasswordRequestBuilder password(char[] password, Hasher hasher) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is breaking the java API, which I think is fine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is or is not ? I Can definitely reintroduce the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the incomplete thought. I think breaking is the right way to go; the issue with a non-breaking change is the default method will be trappy if they configure elasticsearch to use PBKDF2 but we hash with BCrypt on the client side by default. I wonder if we should add validation that the hash is the correct type in TransportChangePasswordAction? |
||
try (SecureString secureString = new SecureString(password)) { | ||
char[] hash = validateAndHashPassword(secureString); | ||
char[] hash = validateAndHashPassword(secureString, hasher); | ||
request.passwordHash(hash); | ||
} | ||
return this; | ||
|
@@ -65,7 +65,8 @@ public ChangePasswordRequestBuilder password(char[] password) { | |
/** | ||
* Populate the change password request from the source in the provided content type | ||
*/ | ||
public ChangePasswordRequestBuilder source(BytesReference source, XContentType xContentType) throws IOException { | ||
public ChangePasswordRequestBuilder source(BytesReference source, XContentType xContentType, Hasher hasher) throws | ||
IOException { | ||
// EMPTY is ok here because we never call namedObject | ||
try (InputStream stream = source.streamInput(); | ||
XContentParser parser = xContentType.xContent() | ||
|
@@ -80,7 +81,7 @@ public ChangePasswordRequestBuilder source(BytesReference source, XContentType x | |
if (token == XContentParser.Token.VALUE_STRING) { | ||
String password = parser.text(); | ||
final char[] passwordChars = password.toCharArray(); | ||
password(passwordChars); | ||
password(passwordChars, hasher); | ||
assert CharBuffer.wrap(passwordChars).chars().noneMatch((i) -> (char) i != (char) 0) : "expected password to " + | ||
"clear the char[] but it did not!"; | ||
} else { | ||
|
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 am not sure if we discussed in the team meeting or somewhere else. Just adding a comment for discussion if we need to have extensible mechanism via security extensions. If need be customers can use 'Argon2' or 'scrypt' using non-default implementations? Is it too early to support them?
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 part has not been discussed, but it is a good idea for a future enhancement. I'd rather wait on opening this up though; once we do that then it has to be supported by us and everything we add creates overhead. We also do not know if there is demand for this and I'd guess that the majority of users would not have a preference as long as we use something that is secure.
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 PR was in the context of supporting a FIPS-140 compliant solution, hence only PBKDF2 was added. I also haven't seen any argon2 or scrypt JAVA implementations that have been used / tested sufficiently (there are bindings for the Argon2 C implementation though.. )
I'm definitely not against allowing for extensions with other algorithm implementations, but not in the context of this PR.
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.
Thank you, Jay and Ioannis. I just thought if this was something that we wanted to consider for security extensions. Yes, I would not trust yet not proven fairly new implementations, just wanted to bring it up so we can keep it in our thoughts.