KeyGenerator是线程安全的吗?

7
我想知道是否可以只实例化javax.crypto.KeyGenerator一次,然后在多线程环境中使用此实例。它的JavaDoc文档没有提到其线程安全性。或者最好使用ThreadLocal<KeyGenerator>方法吗? 更新:一个相关的问题是Is SecureRandom thread safe?虽然JavaDoc没有声明该类是线程安全的,但社区仍然认为决定是线程安全的,这对于实际应用非常重要。我想了解KeyProvider的情况。

1
我认为你误读了SecureRandom的答案。如果文档没有说明它是线程安全的,那么假设它是线程安全的就是一个bug。 - President James K. Polk
3
没有理由认为这是一个漏洞。一个实现是线程安全的事实并不意味着下一个版本也会是线程安全的。唯一的保证就是Javadocs中的内容。 - President James K. Polk
@JamesKPolk 我同意你的观点,我更愿意将其视为非线程安全。但社区认为实际上它是线程安全的。 - Andremoniy
1
社区并没有这样说,只有一个用户@erickson错误地这样说。其他用户指出当前实现是线程安全的。正如我所说,依赖于这种特定于实现的行为是一个bug。 - President James K. Polk
3
“社区”所说的并不重要,唯一重要的是官方文档。 - user207421
显示剩余6条评论
1个回答

7

除非文档明确保证线程安全,否则请将任何内容视为非线程安全。

你说得对,如果缺乏线程安全文档,则这种哲学几乎没有什么帮助......但是如果文档不保证线程安全,那么你就不能假设某些东西是或将继续是线程安全的。


这是一些关于KeyGenerator实际实现的研究,以及为什么我们不能假设它是线程安全的。

我找到了源代码,乍一看,当前的实现似乎是线程安全的。然而,即使我们假设这个实现永远不会改变,它还是调用了Security Providers,这可能是他们自己的任何实现,也没有保证是线程安全的,因为文档上没有说明。


来源摘要:

调用generateKey()使用“密钥生成服务提供程序”调用KeyGeneratorSpi.engineGenerateKey() (可能不是线程安全的)来生成SecretKey

如果您使用特定提供程序构建了KeyGenerator,则它将使用该特定提供程序来生成密钥。

如果您没有使用特定提供程序构建KeyGenerator,则nextSpi()将通过JVM可用提供程序列表进行迭代(线程安全),并尝试生成密钥,直到其中一个起作用或者您用完了提供程序。


主要问题在于文档... 如果文档没有提到线程安全性,那么任何当前实现者或对当前实现的更新可能都不是线程安全的。

因此,您不能简单地假设或依赖于 KeyGenerator 的任何线程安全性。


谢谢,我知道这种方法。但在实际用途中它并不起作用。看看这个问题:https://dev59.com/jXM_5IYBdhLWcg3wPAnU - Andremoniy
3
感谢您的肯定和反馈。虽然您给出的回答很详尽,但是您做了太多的工作!原本简短的回答是正确的。当前实现是否支持线程安全大部分情况下都不重要。实现可能会在明天发生变化,唯一能保证的行为是Java文档中所述。 - President James K. Polk
1
@JamesKPolk 没错,这是一个问题,特别是涉及到 KeyGeneratorSpi,它可能真的是任何东西... - xtratic
3
这个正确答案的要点在于你需要找到线程安全的证据,并在文档中寻找,不应该假设它存在。请注意不改变原意,让内容更加通俗易懂。 - user207421
@EJP,是的,这正是这个答案的重点。KeyGeneratorSpi.engineGenerateKey()的文档没有线程安全要求,因此KeyGenerator方法的线程安全实际上是一个无关紧要的问题。 - xtratic
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接