SecureRandom:线程安全无争用且仍然加密安全?

时间:2017-03-13 10:06:48

标签: java multithreading security cryptography

通过论坛阅读SecureRandom似乎是线程安全的,但由于争用,我在多线程系统中遇到困难,请参阅Is SecureRandom thread safe? 。初始化新的SecureRandom也是一项昂贵的操作。提高性能的一个建议是使用ThreadLocalRandom

所以我改变了我的代码:

SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");

为:

private final ThreadLocalRandom randomThreadLocal = ThreadLocalRandom.current();

我做了一些测试 - 100次运行加密10000个字符串值,我可以看到明确的改进。

**With ThreadLocalRandom**
Thread #18New encryption service took on average: 66.44ms.
Thread #17New encryption service took on average: 64.79ms.
Thread #14New encryption service took on average: 70.77ms.
Thread #13New encryption service took on average: 72.33ms.
Thread #19New encryption service took on average: 73.42ms.
Thread #15New encryption service took on average: 74.21ms.
Thread #11New encryption service took on average: 76.79ms.
Thread #16New encryption service took on average: 78.72ms.
Thread #12New encryption service took on average: 78.95ms.
Thread #20New encryption service took on average: 78.99ms.

**With SecureRandom**
Thread #19New encryption service took on average: 87.26ms.
Thread #18New encryption service took on average: 93.65ms.
Thread #13New encryption service took on average: 93.1ms.
Thread #15New encryption service took on average: 95.81ms.
Thread #16New encryption service took on average: 96.9ms.
Thread #11New encryption service took on average: 97.0ms.
Thread #20New encryption service took on average: 94.93ms.
Thread #17New encryption service took on average: 96.63ms.
Thread #12New encryption service took on average: 97.41ms.
Thread #14New encryption service took on average: 99.08ms.

似乎我在这里确实提高了速度,但是我降低了安全性,因为看起来ThreadLocalRandom在加密方面并不安全:

 * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
 * secure.  Consider instead using {@link java.security.SecureRandom}
 * in security-sensitive applications

我的问题是 - 有没有办法创建加密安全的随机数,这是线程安全的,并且它在多线程系统中表现良好?

还有一个问题涉及这个主题,但答案是建议从SecureRandom - &gt;进行相同的转换。 ThreadLocalRandom,这不是加密安全的,请参阅Minimizing SecureRandom performance problems in multithreaded environment?

1 个答案:

答案 0 :(得分:3)

SecureRandom实施比ThreadLocalRandom慢得多。这与线程安全无关。

ThreadLocalRandom生成下一个随机数的算法涉及很少的数学运算,很容易破解。实际上,单个nextLong操作返回的结果足以确定该生成器生成的所有未来和过去的数字,如果您对详细信息感兴趣,请参阅https://jazzy.id.au/2010/09/20/cracking_random_number_generators_part_1.html

另一方面,SecureRandom与您选择的提供程序一起使用SHA1生成随机数。 SHA1的计算成本很高,因此性能比ThreadLocalRandom差。这是设计的 - 计算复杂性是使SHA1难以逆转的因素之一,并且难以猜测种子。

为了比较我使用两个生成器在单个线程中生成100M随机数的性能。 ThreadLocalRandom完成了95毫秒,SecureRandom花了41秒。

编辑以解决线程性能:

您可以为每个线程创建一个SecureRandom实例。它将在首次使用时使用从静态(共享/同步)实例获取的数据进行初始化,但后续操作将是线程本地的。我使用共享与专用SecureRandom实例测量了4个线程的性能。每个线程生成100M随机数;专用实例花了30秒,共享花了1分54秒。