Java SecureRandom declaration should be static class specific or can be instance specific
Asked Answered
S

2

3

I am trying to use a SecureRandom to generate random numbers in my java project. But I am a little confused as how to keep my object for SecureRandom. Should it be a static class member. I dont intend to call this from outside. Below is my current implementation :

Class MyClass {

    private static final SecureRandom secureRandom = new SecureRandom();

    private long calculate(int noOfRetry){
        final long value = someValueCalculationWith-noOfRetry;
        final float randomNo = secureRandom().nextFloat() + 1;
        return (long) (value*randomNo);
    }
}

Is this the correct way to use SecureRandom in java ?

Synovitis answered 7/7, 2021 at 12:44 Comment(3)
Depends on the context, see here for some very good info re entropy issues #27623125Thurible
Beware that float and double have very interesting properties w.r.t. precision, rounding and randomness. When I see a float or double being used in a security application I always feel a little shudder - something may be out of kilt. Use e.g. nextInt(int max) instead.Spoon
Oh, and this seems to be a random timeout or whatever, beware too that may successfully hides the calculation time of one calculation, but statistics can still provide interesting details. E.g. if you add the minimum additional time to the minimum running time, you'd leak the latter, even for that specific instance. Having a constant time implementation may be better at hiding stuff.Spoon
S
2

No, don't make it static. If you want you can make it an instance field, but making it a class field is not optimal. E.g. see the note on thread-safety on the Random class that it has been derived from:

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.

Beware though that the ThreadLocalRandom is not cryptographically secure, and therefore not a good option for you. In general, you should try and avoid using static class fields, especially when the instances are stateful.

If you only require the random instance in one or a few methods that are not in a tight loop then making it a local instance is perfectly fine (just using var rng = new SecureRandom() in other words, or even just new SecureRandom() if you have a single method call that requires it).

Spoon answered 7/7, 2021 at 13:38 Comment(6)
Thanks Mate ... I got your point. So in the same method I can call the new SecureRandom() multiple times like this : final float randomNo = new SecureRandom().nextFloat() + 1;Synovitis
Just a note here. According to this link SecureRandom is guaranteed to be thread safe bugs.openjdk.java.net/browse/JDK-8165115 Specially there seems to be no need of synchronizing the access to nextFloat and the only synchronized methods are related to the seed and generating byte arrays.Cosby
Well, in the same method I would just create one instance and use a variable. The initialization time for SecureRandom is not that high, but having it once is always better than multiple times.Spoon
@Cosby Of course, that should be the case because - as a child class - it needs to adhere to the specifications for Random. That's why I included a quote from the JavaDoc of that class. That implementation just allows for the SecureRandomSpito rely on SecureRandom for thread safety, it seems. Maybe some external providers didn't read the Random class documentation :)Spoon
I do not see anything in your writeup that justifies describing static use as "dangerous". Potentially slow maybe, but not dangerous.Terrie
Yeah, good point, I'll adjust it. It could be a problem for Java 8 in case a provider implementation is not thread safe, but that's about it.Spoon
B
0

I totally agree with Maartens's answer. However one can notice that java.util classes create statics for SecureRandom themselfes.

public final class UUID implements java.io.Serializable, Comparable<UUID> {

    ...

    /*
     * The random number generator used by this class to create random
     * based UUIDs. In a holder class to defer initialization until needed.
     */
    private static class Holder {
        static final SecureRandom numberGenerator = new SecureRandom();
    }
Bernete answered 22/11, 2021 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.