Skip to content

Commit

Permalink
ELY-2731 Use SecureRandom instead of ThreadLocalRandom
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasHofman committed Mar 18, 2024
1 parent 0ddd49c commit 04d4445
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

import org.wildfly.security.password.interfaces.BSDUnixDESCryptPassword;
import org.wildfly.security.password.spec.ClearPasswordSpec;
Expand Down Expand Up @@ -72,19 +71,19 @@ class BSDUnixDESCryptPasswordImpl extends AbstractPasswordImpl implements BSDUni
}

BSDUnixDESCryptPasswordImpl(final ClearPasswordSpec passwordSpec) throws InvalidKeySpecException {
this(passwordSpec.getEncodedPassword(), ThreadLocalRandom.current().nextInt() & 0xffffff, DEFAULT_ITERATION_COUNT);
this(passwordSpec.getEncodedPassword(), PasswordUtil.generateRandomSaltInt() & 0xffffff, DEFAULT_ITERATION_COUNT);
}

BSDUnixDESCryptPasswordImpl(final char[] password, final Charset hashCharset) throws InvalidKeySpecException, InvalidParameterSpecException {
this(password, ThreadLocalRandom.current().nextInt() & 0xffffff, DEFAULT_ITERATION_COUNT, hashCharset);
this(password, PasswordUtil.generateRandomSaltInt() & 0xffffff, DEFAULT_ITERATION_COUNT, hashCharset);
}

BSDUnixDESCryptPasswordImpl(final char[] password, final IteratedSaltedPasswordAlgorithmSpec spec, final Charset hashCharset) throws InvalidKeySpecException, InvalidParameterSpecException {
this(password, getSaltValue(spec.getSalt()), spec.getIterationCount(), hashCharset);
}

BSDUnixDESCryptPasswordImpl(final char[] password, final IteratedPasswordAlgorithmSpec spec, final Charset hashCharset) throws InvalidKeySpecException, InvalidParameterSpecException {
this(password, ThreadLocalRandom.current().nextInt() & 0xffffff, spec.getIterationCount(), hashCharset);
this(password, PasswordUtil.generateRandomSaltInt() & 0xffffff, spec.getIterationCount(), hashCharset);
}

BSDUnixDESCryptPasswordImpl(final char[] password, final SaltedPasswordAlgorithmSpec spec, final Charset hashCharset) throws InvalidKeySpecException, InvalidParameterSpecException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
package org.wildfly.security.password.impl;

import java.util.concurrent.ThreadLocalRandom;
import java.security.SecureRandom;

/**
* Helper utility methods for operations on passwords.
Expand All @@ -27,6 +27,8 @@
*/
final class PasswordUtil {

private static final SecureRandom RANDOM = new SecureRandom();

/**
* Generate a random salt as byte array.
*
Expand All @@ -35,7 +37,24 @@ final class PasswordUtil {
*/
public static byte[] generateRandomSalt(int saltSize) {
byte[] randomSalt = new byte[saltSize];
ThreadLocalRandom.current().nextBytes(randomSalt);
RANDOM.nextBytes(randomSalt);
return randomSalt;
}

/**
* Generate a random salt as int.
*
* @return a byte array representing the random salt
*/
public static int generateRandomSaltInt() {
byte[] saltBytes = generateRandomSalt(4);
return convertBytesToInt(saltBytes);
}

static int convertBytesToInt(byte[] saltBytes) {
if (saltBytes.length != 4) {
throw new IllegalArgumentException("4 bytes are needed for conversion to int, bytes given: " + saltBytes.length);
}
return (saltBytes[0] & 0xff) << 24 | (saltBytes[1] & 0xff) << 16 | (saltBytes[2] & 0xff) << 8 | saltBytes[3] & 0xff;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

import org.wildfly.security.password.interfaces.UnixDESCryptPassword;
import org.wildfly.security.password.spec.ClearPasswordSpec;
Expand Down Expand Up @@ -68,11 +67,11 @@ class UnixDESCryptPasswordImpl extends AbstractPasswordImpl implements UnixDESCr
}

UnixDESCryptPasswordImpl(final ClearPasswordSpec spec) throws InvalidKeySpecException, InvalidKeyException {
this((short) (ThreadLocalRandom.current().nextInt() & 0xfff), spec.getEncodedPassword());
this((short) (PasswordUtil.generateRandomSaltInt() & 0xfff), spec.getEncodedPassword());
}

UnixDESCryptPasswordImpl(final char[] passwordChars, final Charset hashCharset) throws InvalidKeyException {
this((short) (ThreadLocalRandom.current().nextInt() & 0xfff), passwordChars, hashCharset);
this((short) (PasswordUtil.generateRandomSaltInt() & 0xfff), passwordChars, hashCharset);
}

UnixDESCryptPasswordImpl(final char[] passwordChars, SaltedPasswordAlgorithmSpec algorithmSpec, final Charset hashCharset) throws InvalidParameterSpecException, InvalidKeyException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.wildfly.security.password.impl;

import org.junit.Assert;
import org.junit.Test;

public class PasswordUtilTest {

@Test
public void testConvertBytesToInt() {
Assert.assertEquals(0, PasswordUtil.convertBytesToInt(new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}));
Assert.assertEquals(Integer.MAX_VALUE, PasswordUtil.convertBytesToInt(new byte[] {(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff}));
Assert.assertEquals(Integer.MIN_VALUE, PasswordUtil.convertBytesToInt(new byte[] {(byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00}));
Assert.assertEquals(-1, PasswordUtil.convertBytesToInt(new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}));
}
}

0 comments on commit 04d4445

Please sign in to comment.