How to deal with a slow SecureRandom generator?

后端 未结 17 989
时光说笑
时光说笑 2020-11-22 11:56

If you want a cryptographically strong random numbers in Java, you use SecureRandom. Unfortunately, SecureRandom can be very slow. If it uses

相关标签:
17条回答
  • 2020-11-22 12:17

    There is a tool (on Ubuntu at least) that will feed artificial randomness into your system. The command is simply:

    rngd -r /dev/urandom
    

    and you may need a sudo at the front. If you don't have rng-tools package, you will need to install it. I tried this, and it definitely helped me!

    Source: matt vs world

    0 讨论(0)
  • 2020-11-22 12:17

    I haven't hit against this problem myself, but I'd spawn a thread at program start which immediately tries to generate a seed, then dies. The method which you call for randoms will join to that thread if it is alive so the first call only blocks if it occurs very early in program execution.

    0 讨论(0)
  • 2020-11-22 12:18

    Many Linux distros (mostly Debian-based) configure OpenJDK to use /dev/random for entropy.

    /dev/random is by definition slow (and can even block).

    From here you have two options on how to unblock it:

    1. Improve entropy, or
    2. Reduce randomness requirements.

    Option 1, Improve entropy

    To get more entropy into /dev/random, try the haveged daemon. It's a daemon that continuously collects HAVEGE entropy, and works also in a virtualized environment because it doesn't require any special hardware, only the CPU itself and a clock.

    On Ubuntu/Debian:

    apt-get install haveged
    update-rc.d haveged defaults
    service haveged start
    

    On RHEL/CentOS:

    yum install haveged
    systemctl enable haveged
    systemctl start haveged
    

    Option 2. Reduce randomness requirements

    If for some reason the solution above doesn't help or you don't care about cryptographically strong randomness, you can switch to /dev/urandom instead, which is guaranteed not to block.

    To do it globally, edit the file jre/lib/security/java.security in your default Java installation to use /dev/urandom (due to another bug it needs to be specified as /dev/./urandom).

    Like this:

    #securerandom.source=file:/dev/random
    securerandom.source=file:/dev/./urandom
    

    Then you won't ever have to specify it on the command line.


    Note: If you do cryptography, you need good entropy. Case in point - android PRNG issue reduced the security of Bitcoin wallets.

    0 讨论(0)
  • 2020-11-22 12:18

    The problem you referenced about /dev/random is not with the SecureRandom algorithm, but with the source of randomness that it uses. The two are orthogonal. You should figure out which one of the two is slowing you down.

    Uncommon Maths page that you linked explicitly mentions that they are not addressing the source of randomness.

    You can try different JCE providers, such as BouncyCastle, to see if their implementation of SecureRandom is faster.

    A brief search also reveals Linux patches that replace the default implementation with Fortuna. I don't know much more about this, but you're welcome to investigate.

    I should also mention that while it's very dangerous to use a badly implemented SecureRandom algorithm and/or randomness source, you can roll your own JCE Provider with a custom implementation of SecureRandomSpi. You will need to go through a process with Sun to get your provider signed, but it's actually pretty straightforward; they just need you to fax them a form stating that you're aware of the US export restrictions on crypto libraries.

    0 讨论(0)
  • 2020-11-22 12:19

    If you want truly "cryptographically strong" randomness, then you need a strong entropy source. /dev/random is slow because it has to wait for system events to gather entropy (disk reads, network packets, mouse movement, key presses, etc.).

    A faster solution is a hardware random number generator. You may already have one built-in to your motherboard; check out the hw_random documentation for instructions on figuring out if you have it, and how to use it. The rng-tools package includes a daemon which will feed hardware generated entropy into /dev/random.

    If a HRNG is not available on your system, and you are willing to sacrifice entropy strength for performance, you will want to seed a good PRNG with data from /dev/random, and let the PRNG do the bulk of the work. There are several NIST-approved PRNG's listed in SP800-90 which are straightforward to implement.

    0 讨论(0)
  • 2020-11-22 12:21

    Something else to look at is the property securerandom.source in file lib/security/java.security

    There may be a performance benefit to using /dev/urandom rather than /dev/random. Remember that if the quality of the random numbers is important, don't make a compromise which breaks security.

    0 讨论(0)
提交回复
热议问题