Cipher 线程安全吗?

Posted

技术标签:

【中文标题】Cipher 线程安全吗?【英文标题】:Is Cipher thread-safe? 【发布时间】:2011-10-20 21:46:18 【问题描述】:

很简单,javax.crypto.Cipher 的一个实例(例如Cipher.getInstance("RSA"))可以从多个线程中使用,还是我需要将多个实例粘贴在ThreadLocal 中(在我的情况下)?

【问题讨论】:

【参考方案1】:

不,不是。该实例是有状态的。因此,您需要将其存储在线程本地,或者在每次加密/解密调用时获取一个新实例,或者将其包装在 synchronized(cipher) 块中。

线程安全通常在 javadocs 中被称为“is thread safe”或“is not thread safe”。 Cipher 不是这种情况,所以你不应该假设它是线程安全的。

【讨论】:

【参考方案2】:

如果没有同步,我不会使用来自多个线程的 Cipher 对象。当您查看 API 时,有些方法只能通过更改内部状态来工作,例如 init()update()。这使得它们隐含地是非线程安全的。

【讨论】:

From JavaDocs for Cipher init(): “注意,当一个 Cipher 对象被初始化时,它会失去所有先前获得的状态。换句话说,初始化一个 Cipher 相当于创建一个新的实例加密并初始化它。” docs.oracle.com/javase/7/docs/api/javax/crypto/… 说得对@ddso【参考方案3】:

即使 Cipher 是线程安全的,从多个线程同时使用它也不会真正有用。

您放入和取出密码的字节(通过其updatefinish 方法)是一个连续的流。这意味着,另一方面,它们必须以相同的顺序传递才能有意义。如果您只有一个线程执行此操作,这是最容易完成的。

如果您使用多个线程,您通常希望在两次调用之间调用reset - 然后无论如何您都需要外部同步。

【讨论】:

【参考方案4】:

密码不是线程安全的。

如果您使用多线程来提高性能并且不想进行同步,则可以使用 Jasypt (http://www.jasypt.org/general-usage.html),它具有池化加密器:PooledPBEByteEncryptor、PooledPBEStringEncryptor。

如果同步对您来说没问题并且您使用 Spring。您可以使用加密器 (https://docs.spring.io/spring-security/site/docs/4.2.5.RELEASE/apidocs/org/springframework/security/crypto/encrypt/Encryptors.html)。他们在内部进行同步以访问 Cipher。

【讨论】:

以上是关于Cipher 线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

c++ string线程安全吗

java priorityblockingqueue 线程安全吗

mongodatabase mongocollection 线程安全吗

可以从多个线程等待相同的任务 - 等待线程安全吗?

可以从多个线程等待相同的任务 - 等待线程安全吗?

SecureRandom 线程安全吗?