UUID.randomUUID()是否适合用作一次性密码?

cqc*_*law 24 java security random uuid

正如前面所讨论的,确认电子邮件应该有一个独特的,(几乎)未猜测的代码-基本上是一个一次性密码 --in确认链接.

UUID.randomUUID()文档说:

使用加密强伪随机数生成器生成UUID.

这是否意味着正确实现的JVM中的UUID随机生成器适合用作唯一的(实际上)不可猜测的OTP?

and*_*oke 14

如果你看过RFC链接到从API文档定义的UUID,并且,你会看到UUID的不是所有的位实际上是随机的(以下简称"变体"和"版本"是不是随机的).因此,如果正确实现,类型4 UUID(您打算使用的类型)应该具有122位(对于此实现是安全的)随机信息,总大小为128位.

所以是的,它将与"安全"生成器中的122位随机数一样有效. 但是较短的值可能包含足够的随机性并且可能对用户来说更容易(也许我是唯一一个仍在终端中阅读电子邮件的老式人,但是包含在行之间的确认URL很烦人....) .

  • 实际上,RFC明确告诫不要使用UUID作为安全令牌:"不要假设UUID难以猜测;例如,它们不应被用作安全功能(仅仅拥有访问权限的标识符)." 使用安全RNG**生成的UUID4几乎不可能猜测,但标准明确允许不安全的RNG(!).http://tools.ietf.org/html/rfc4122#section-6(为复活一条非常古老的评论而道歉,但安全性是每个人都关注的问题.) (8认同)

Ale*_*ood 10

是的,使用 ajava.util.UUID很好,randomUUID方法从加密安全源生成。没有更多需要说的了。

这是我的建议:

  1. 向用户发送一个包含巨大密码的链接作为 URL 参数。
  2. 当用户单击链接时,编写您的后端,以便它确定参数是否正确以及用户是否已登录。
  3. 在 UUID 发出 24 小时后使其失效。

这需要一些工作,但如果您真的关心编写一个健壮、安全的系统,这是必要的。

  • @cqcallaw 如果用户从不访问 url 怎么办?我总是在第一次使用后或几个小时后使这些密钥无效,无论是第一次。 (2认同)

jch*_*ook 6

不.根据UUID规范:

不要以为UUID难以猜测; 例如,它们不应被用作安全功能(仅仅拥有访问权限的标识符).可预测的随机数源将加剧这种情况.

此外,UUID只有16个可能的字符(0到F).您可以使用SecureRandom(感谢@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • UUID spec!= Java实现.虽然规范不要求UUID是安全的,但Java实现实际上提供了122位的安全随机性.另见http://stackoverflow.com/a/7532965/47528 (6认同)
  • 我仍然建议明确使用加密库. (2认同)
  • 是的,绝对是 ;-) 在安全方面,最好谨慎和明确。您不会将 UUID.randomUUID() 用于军用级系统。但如果问题是“我是否通过将 UUID.randomUUID() 用于令牌来引入安全漏洞?” 那么答案是否定的。 (2认同)
  • 感谢您的反馈。编辑以包含解决方案。 (2认同)