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 0de4e93e3..710d7d292 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 @@ -18,6 +18,7 @@ package org.jivesoftware.smack.util; import java.io.UnsupportedEncodingException; +import java.security.SecureRandom; import java.util.Collection; import java.util.Iterator; import java.util.Random; @@ -174,7 +175,7 @@ public class StringUtils { * @param length the desired length of the random String to return. * @return a random String of numbers and letters of the specified length. */ - public static String randomString(int length) { + public static String insecureRandomString(int length) { if (length < 1) { return null; } @@ -186,6 +187,31 @@ public class StringUtils { return new String(randBuffer); } + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + + public static String randomString(final int length) { + if (length < 1) { + return null; + } + + byte[] randomBytes = new byte[length]; + SECURE_RANDOM.nextBytes(randomBytes); + char[] randomChars = new char[length]; + for (int i = 0; i < length; i++) { + randomChars[i] = getPrintableChar(randomBytes[i]); + } + return new String(randomChars); + } + + private static char getPrintableChar(byte indexByte) { + assert(numbersAndLetters.length < Byte.MAX_VALUE * 2); + + // Convert indexByte as it where an unsigned byte by promoting it to int + // and masking it with 0xff. Yields results from 0 - 254. + int index = indexByte & 0xff; + return numbersAndLetters[index % numbersAndLetters.length]; + } + /** * Returns true if CharSequence is not null and is not empty, false otherwise. * Examples: diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/IntTestUtil.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/IntTestUtil.java index 83ce1dab3..043efbbcc 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/IntTestUtil.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/IntTestUtil.java @@ -42,8 +42,8 @@ public class IntTestUtil { public static UsernameAndPassword registerAccount(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return registerAccount(connection, StringUtils.randomString(12), - StringUtils.randomString(12)); + return registerAccount(connection, StringUtils.insecureRandomString(12), + StringUtils.insecureRandomString(12)); } public static UsernameAndPassword registerAccount(XMPPConnection connection, String username, diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 1e400ea5a..418a530d8 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -519,7 +519,7 @@ public class SmackIntegrationTestFramework { accountUsername = USERNAME_PREFIX + '-' + middlefix + '-' +testRunResult.testRunId; } if (StringUtils.isNullOrEmpty(accountPassword)) { - accountPassword = StringUtils.randomString(16); + accountPassword = StringUtils.insecureRandomString(16); } // @formatter:off Builder builder = XMPPTCPConnectionConfiguration.builder() @@ -584,7 +584,7 @@ public class SmackIntegrationTestFramework { } public static final class TestRunResult { - public final String testRunId = StringUtils.randomString(5); + public final String testRunId = StringUtils.insecureRandomString(5); private final List successfulTests = Collections.synchronizedList(new LinkedList()); private final List failedIntegrationTests = Collections.synchronizedList(new LinkedList()); private final List impossibleTestMethods = Collections.synchronizedList(new LinkedList()); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java index a6de85959..f7fbc6b8e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java @@ -52,7 +52,7 @@ public class LoginIntegrationTest extends AbstractSmackLowLevelIntegrationTest { @SmackIntegrationTest public void testInvalidLogin() throws SmackException, IOException, XMPPException, InterruptedException, KeyManagementException, NoSuchAlgorithmException { - final String nonExistentUserString = StringUtils.randomString(24); + final String nonExistentUserString = StringUtils.insecureRandomString(24); XMPPTCPConnectionConfiguration conf = getConnectionConfiguration().setUsernameAndPassword( nonExistentUserString, "invalidPassword").build(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java index 7f883e08b..59d527230 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java @@ -43,7 +43,7 @@ public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { ftManagerTwo = FileTransferManager.getInstanceFor(conTwo); } - private static final byte[] dataToSend = StringUtils.randomString(1024 * 4 * 5).getBytes(); + private static final byte[] dataToSend = StringUtils.insecureRandomString(1024 * 4 * 5).getBytes(); @SmackIntegrationTest public void fileTransferTest() throws Exception { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 6d905d611..1951b431d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -39,7 +39,7 @@ import org.jxmpp.jid.parts.Resourcepart; public class MultiUserChatIntegrationTest extends AbstractSmackIntegrationTest { - private final String randomString = StringUtils.randomString(6); + private final String randomString = StringUtils.insecureRandomString(6); private final MultiUserChatManager mucManagerOne; private final MultiUserChatManager mucManagerTwo;