这是否意味着在正确实现的JVM中,UUID随机生成器适用于用作唯一的、(实际上)难以猜测的OTP?使用加密强度很高的伪随机数生成器生成UUID。
这是否意味着在正确实现的JVM中,UUID随机生成器适用于用作唯一的、(实际上)难以猜测的OTP?使用加密强度很高的伪随机数生成器生成UUID。
如果您阅读了定义UUID的RFC(从API文档链接过去),就会发现UUID的并非所有位都是随机的(“变体”和“版本”不是随机的)。因此,如果正确实现,类型4 UUID(您打算使用的类型)应具有128位总大小中122位(对于此实现来说是安全的)随机信息。
因此,是的,它将像“安全”发生器生成的122位随机数一样工作。但是,较短的值可能包含足够数量的随机性,并且可能更容易供用户使用(也许我是仅有的在终端上读取电子邮件的守旧人,但是跨行包装的确认URL令人讨厌…)。
不可以。根据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);
}
}
附言:
我想举一个明显的例子,说明使用UUID作为安全令牌可能会导致问题:
在uuid-random中,我们通过巧妙地内部重新使用随机字节,发现极大的速度提升,从而导致可预测的UUID。虽然我们没有发布这个更改,但RFC允许它,这样的优化可能会悄悄地进入您的UUID库中。
是的,使用java.util.UUID
是可以的,其中的randomUUID
方法是从加密安全源生成的。没有更多需要说明的了。
这是我的建议:
这需要一些工作,但如果您真正关心编写一个强大、安全的系统,这是必要的。
62
(26 * 2 + 10)。随机代码用于确认链接的目的是让攻击者无法猜测或预测其值。正如您所见,要找到正确的确认链接代码,128位长度的UUID会产生2^128种不同的可能代码,也就是说有340,282,366,920,938,463,463,374,607,431,768,211,456个可尝试的代码。我想您的确认链接并不是用来发射核武器的,对吧?这对攻击者来说已经足够难以猜测了。它是安全的。
-- 更新 --
如果您不信任提供的具有密码学强度的随机数生成器,您可以将一些更加不可预测的参数与UUID代码一起混合并进行哈希处理。例如:
code = SHA1(UUID, 进程PID, 线程ID, 本地连接端口号, CPU温度)
这样做将使其更加难以预测。
java.util.Random
可以用来获取 128 比特的数据,但这并不意味着它是安全的。 - Louis Wassermanjava.util.Random
更安全,但这个回答没有给出任何原因的提示。 - Louis Wasserman我认为这应该是合适的,因为它是随机生成的,而不是来自任何特定的输入(例如您没有用用户名之类的东西来喂它)- 因此对此代码的多次调用将产生不同的结果。它声明了一个128位密钥,因此足够长,以至于破解变得不切实际。
那么你接下来会使用这个密钥来加密一个值,还是期望将其作为实际密码使用?无论如何,您都需要重新解释密钥,以便以键盘可以输入的格式输入。例如,进行Base64或Hex转换,或以某种方式将值映射到字母数字,否则用户将尝试输入键盘上不存在的字节值。
它非常适合作为一次性密码,因为我甚至已经在我正在工作的应用程序中实现了相同的功能。此外,您分享的链接已经说明了一切。