Skip to content

Commit f7abb1a

Browse files
committed
Make hashed token ids url safe (#42651)
This commit changes the way token ids are hashed so that the output is url safe without requiring encoding. This follows the pattern that we use for document ids that are autogenerated, see UUIDs and the associated classes for additional details.
1 parent 64e9c88 commit f7abb1a

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/support/Hasher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,14 @@ public boolean verify(SecureString text, char[] hash) {
360360
public char[] hash(SecureString text) {
361361
MessageDigest md = MessageDigests.sha256();
362362
md.update(CharArrays.toUtf8Bytes(text.getChars()));
363-
return Base64.getEncoder().encodeToString(md.digest()).toCharArray();
363+
return Base64.getUrlEncoder().withoutPadding().encodeToString(md.digest()).toCharArray();
364364
}
365365

366366
@Override
367367
public boolean verify(SecureString text, char[] hash) {
368368
MessageDigest md = MessageDigests.sha256();
369369
md.update(CharArrays.toUtf8Bytes(text.getChars()));
370-
return CharArrays.constantTimeEquals(Base64.getEncoder().encodeToString(md.digest()).toCharArray(), hash);
370+
return CharArrays.constantTimeEquals(Base64.getUrlEncoder().withoutPadding().encodeToString(md.digest()).toCharArray(), hash);
371371
}
372372
},
373373

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public final class TokenService {
181181
TimeValue.MINUS_ONE, Property.NodeScope);
182182

183183
static final String TOKEN_DOC_TYPE = "token";
184-
private static final int HASHED_TOKEN_LENGTH = 44;
184+
private static final int HASHED_TOKEN_LENGTH = 43;
185185
// UUIDs are 16 bytes encoded base64 without padding, therefore the length is (16 / 3) * 4 + ((16 % 3) * 8 + 5) / 6 chars
186186
private static final int TOKEN_LENGTH = 22;
187187
private static final String TOKEN_DOC_ID_PREFIX = TOKEN_DOC_TYPE + "_";

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/TokenServiceTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@
6060
import org.junit.Before;
6161
import org.junit.BeforeClass;
6262

63+
import javax.crypto.SecretKey;
6364
import java.io.IOException;
65+
import java.net.URLEncoder;
66+
import java.nio.charset.StandardCharsets;
6467
import java.security.GeneralSecurityException;
6568
import java.time.Clock;
6669
import java.time.Instant;
@@ -70,8 +73,6 @@
7073
import java.util.HashMap;
7174
import java.util.Map;
7275

73-
import javax.crypto.SecretKey;
74-
7576
import static java.time.Clock.systemUTC;
7677
import static org.elasticsearch.repositories.ESBlobStoreTestCase.randomBytes;
7778
import static org.elasticsearch.test.ClusterServiceUtils.setState;
@@ -722,6 +723,11 @@ public void testCannotValidateTokenIfLicenseDoesNotAllowTokens() throws Exceptio
722723
assertThat(authToken, Matchers.nullValue());
723724
}
724725

726+
public void testHashedTokenIsUrlSafe() throws Exception {
727+
final String hashedId = TokenService.hashTokenString(UUIDs.randomBase64UUID());
728+
assertEquals(hashedId, URLEncoder.encode(hashedId, StandardCharsets.UTF_8.name()));
729+
}
730+
725731
private TokenService createTokenService(Settings settings, Clock clock) throws GeneralSecurityException {
726732
return new TokenService(settings, clock, client, licenseState, securityMainIndex, securityTokensIndex, clusterService);
727733
}

0 commit comments

Comments
 (0)