-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Reduce api key verification cost #112878
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
Reduce api key verification cost #112878
Changes from all commits
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 |
|---|---|---|
|
|
@@ -36,8 +36,8 @@ | |
| import org.elasticsearch.client.internal.Client; | ||
| import org.elasticsearch.cluster.node.DiscoveryNode; | ||
| import org.elasticsearch.cluster.service.ClusterService; | ||
| import org.elasticsearch.common.SecureRandomHolder; | ||
| import org.elasticsearch.common.Strings; | ||
| import org.elasticsearch.common.UUIDs; | ||
| import org.elasticsearch.common.bytes.BytesArray; | ||
| import org.elasticsearch.common.bytes.BytesReference; | ||
| import org.elasticsearch.common.cache.Cache; | ||
|
|
@@ -160,7 +160,7 @@ public class ApiKeyService implements Closeable { | |
|
|
||
| public static final Setting<String> PASSWORD_HASHING_ALGORITHM = XPackSettings.defaultStoredHashAlgorithmSetting( | ||
| "xpack.security.authc.api_key.hashing.algorithm", | ||
| (s) -> Hasher.PBKDF2.name() | ||
| (s) -> Hasher.SSHA256.name() | ||
|
Contributor
Author
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. There is currently no |
||
| ); | ||
| public static final Setting<TimeValue> DELETE_TIMEOUT = Setting.timeSetting( | ||
| "xpack.security.authc.api_key.delete.timeout", | ||
|
|
@@ -541,7 +541,9 @@ private void createApiKeyAndIndexIt( | |
| ) { | ||
| final Instant created = clock.instant(); | ||
| final Instant expiration = getApiKeyExpiration(created, request.getExpiration()); | ||
| final SecureString apiKey = UUIDs.randomBase64UUIDSecureString(); | ||
| // the difference between 16 and 18 effectively results in the same "encoded" API Key that's sent in HTTP request headers, | ||
| // dues to base64 padding | ||
| final SecureString apiKey = getBase64SecureRandomString(request.getType() == ApiKey.Type.CROSS_CLUSTER ? 16 : 18); | ||
| assert ApiKey.Type.CROSS_CLUSTER != request.getType() || API_KEY_SECRET_LENGTH == apiKey.length() | ||
| : "Invalid API key (name=[" + request.getName() + "], type=[" + request.getType() + "], length=[" + apiKey.length() + "])"; | ||
|
Comment on lines
+544
to
548
Contributor
Author
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. As @n1v0lg pointed out, we'd need to support the current length for cross cluster API keys.
Contributor
Author
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. e.g.: The |
||
|
|
||
|
|
@@ -2725,4 +2727,22 @@ public void invalidateAll() { | |
| roleDescriptorsBytesCache.invalidateAll(); | ||
| } | ||
| } | ||
|
|
||
| private static SecureString getBase64SecureRandomString(int randomBytesCount) { | ||
| byte[] randomBytes = null; | ||
| byte[] encodedBytes = null; | ||
| try { | ||
| randomBytes = new byte[randomBytesCount]; | ||
| SecureRandomHolder.INSTANCE.nextBytes(randomBytes); | ||
| encodedBytes = Base64.getUrlEncoder().withoutPadding().encode(randomBytes); | ||
| return new SecureString(CharArrays.utf8BytesToChars(encodedBytes)); | ||
| } finally { | ||
| if (randomBytes != null) { | ||
| Arrays.fill(randomBytes, (byte) 0); | ||
| } | ||
| if (encodedBytes != null) { | ||
| Arrays.fill(encodedBytes, (byte) 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
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 needs to be allowed only for API keys, not for passwords (api keys are random long secrets).