From 1cc9cec677950f801e7a293ae1a287050f2c6af5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 10 Mar 2017 17:16:53 +0100 Subject: [PATCH] Use thread local variables for (Secure)Randoms --- .../smack/sasl/core/ScramMechanism.java | 13 ++++++++--- .../jivesoftware/smack/util/StringUtils.java | 22 ++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java index 08a1f6aab..edeedb665 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2016 Florian Schmaus + * Copyright 2014-2017 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.security.SecureRandom; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Random; import javax.security.auth.callback.CallbackHandler; @@ -41,7 +42,12 @@ public abstract class ScramMechanism extends SASLMechanism { private static final byte[] SERVER_KEY_BYTES = toBytes("Server Key"); private static final byte[] ONE = new byte[] { 0, 0, 0, 1 }; - private static final SecureRandom RANDOM = new SecureRandom(); + private static final ThreadLocal SECURE_RANDOM = new ThreadLocal() { + @Override + protected SecureRandom initialValue() { + return new SecureRandom(); + } + }; private static final Cache CACHE = new LruCache(10); @@ -292,8 +298,9 @@ public abstract class ScramMechanism extends SASLMechanism { String getRandomAscii() { int count = 0; char[] randomAscii = new char[RANDOM_ASCII_BYTE_COUNT]; + final Random random = SECURE_RANDOM.get(); while (count < RANDOM_ASCII_BYTE_COUNT) { - int r = RANDOM.nextInt(128); + int r = random.nextInt(128); char c = (char) r; // RFC 5802 ยง 5.1 specifies 'r:' to exclude the ',' character and to be only printable ASCII characters if (!isPrintableNonCommaAsciiChar(c)) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index e61b15650..94e528099 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2017 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -271,7 +271,12 @@ public class StringUtils { * The Random class is not considered to be cryptographically secure, so * only use these random Strings for low to medium security applications. */ - private static final Random randGen = new Random(); + private static final ThreadLocal randGen = new ThreadLocal() { + @Override + protected Random initialValue() { + return new Random(); + } + }; /** * Array of numbers and letters of mixed case. Numbers appear in the list @@ -299,15 +304,22 @@ public class StringUtils { if (length < 1) { return null; } + + final Random random = randGen.get(); // Create a char buffer to put random letters and numbers in. char [] randBuffer = new char[length]; for (int i=0; i SECURE_RANDOM = new ThreadLocal() { + @Override + protected SecureRandom initialValue() { + return new SecureRandom(); + } + }; public static String randomString(final int length) { if (length < 1) { @@ -315,7 +327,7 @@ public class StringUtils { } byte[] randomBytes = new byte[length]; - SECURE_RANDOM.nextBytes(randomBytes); + SECURE_RANDOM.get().nextBytes(randomBytes); char[] randomChars = new char[length]; for (int i = 0; i < length; i++) { randomChars[i] = getPrintableChar(randomBytes[i]);