Is UUID.randomUUID() suitable for use as a one-tim

2019-02-02 23:42发布

As previous discussed, confirmation emails should have a unique, (practically) un-guessable code--essentially a one-time password--in the confirmation link.

The UUID.randomUUID() docs say:

The UUID is generated using a cryptographically strong pseudo random number generator.

Does this imply that the the UUID random generator in a properly implemented JVM is suitable for use as the unique, (practically) un-guessable OTP?

8条回答
劫难
2楼-- · 2019-02-03 00:12

if you read the RFC that defines UUIDs, and which is linked to from the API docs, you'll see that not all bits of the UUID are actually random (the "variant" and the "version" are not random). so a type 4 UUID (the kind that you intend to use), if implemented correctly, should have 122 bits of (secure, for this implementation) random information, out of a total size of 128 bits.

so yes, it will work as well as a 122 bit random number from a "secure" generator. but a shorter value may contain a sufficient amount of randomness and might be easier for a user (maybe i am the only old-fashioned person who still reads email in a terminal, but confirmation URLs that wrap across lines are annoying....).

查看更多
Deceive 欺骗
3楼-- · 2019-02-03 00:13

The point of the random code for a confirmation link is that the attacker should not be able to guess nor predict the value. As you can see, to find the correct code to your confirmation link, a 128bits length UUID yields 2^128 different possible codes, namely, 340,282,366,920,938,463,463,374,607,431,768,211,456 possible codes to try. I think your confirmation link is not for launching a nuclear weapon, right? This is difficult enough for attacker to guess. It's secure.

-- update --

If you don't trust the cryptographically strong random number generator provided, you can put some more unpredictable parameters with the UUID code and hash them. For example,

code = SHA1(UUID, Process PID, Thread ID, Local connection port number, CPU temperature)

This make it even harder to predict.

查看更多
放我归山
4楼-- · 2019-02-03 00:15

Yes, using a java.util.UUID is fine. There's not much more that needs to be said.

Here's my suggestion:

  1. Send the user a link with a huge password in it as the URL argument.
  2. When user clicks the link, write your backend so that it will determine whether or not the argument is correct and that the user is logged in.
  3. Invalidate the UUID 24 hours after it has been issued.

This will take some work, but it's necessary if you really care about writing a robust, secure system.

查看更多
Anthone
5楼-- · 2019-02-03 00:20

No. According to the UUID spec:

Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.

Also, UUIDs only have 16 possible characters (0 through F). You can generate a much more compact and explicitly secure random password using SecureRandom (thanks to @erickson).

import java.security.SecureRandom;
import java.math.BigInteger;

public final class PasswordGenerator {
    private SecureRandom random = new SecureRandom();

    public String nextPassword() {
        return new BigInteger(130, random).toString(32);
    }
}
查看更多
Ridiculous、
6楼-- · 2019-02-03 00:23

If it's generated by a CSRNG then it's unpredictable and so can be used.

But the trouble you're going to is wasted if you're sending out confirmation emails unencrypted - if an attacker has the means of predicting RNG results from your system then chances are they can intercept emails too.

UUIDs are also long strings (128-bits then typically Base64 (22 chars) or Base16-encoded (32 chars)) - think about how user-friendly your system will be. Personally I'd use a CSRNG to select 8 alphanumeric characters at random and return those.

查看更多
狗以群分
7楼-- · 2019-02-03 00:23

I think java.util.UUID should be fine. You can find more information from this article:

查看更多
登录 后发表回答