Cipher线程安全吗?

时间:2011-08-05 13:52:30

标签: java multithreading thread-safety encryption

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

4 个答案:

答案 0 :(得分:86)

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

线程安全通常在javadocs中提到explicitlyCipher不是这种情况,所以你不应该认为它是线程安全的。

答案 1 :(得分:7)

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

答案 2 :(得分:7)

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

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

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

答案 3 :(得分:1)

密码不是线程安全的。

如果您使用多线程来提高性能并且不想执行同步,则可以使用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)。他们在内部进行同步以访问密码。