Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Cipher thread-safe?

Quite simply, can one instance of javax.crypto.Cipher (e.g. Cipher.getInstance("RSA")) be used from multiple threads, or do I need to stick multiple of them in a ThreadLocal (in my case)?

like image 642
Bart van Heukelom Avatar asked Aug 05 '11 13:08

Bart van Heukelom


People also ask

Is SecretKeySpec thread-safe?

Yes, SecretKeySpec is thread-safe, for the simple reason that it's immutable.

Is bouncy castle thread-safe?

It's not completely thread safe (atleast AES engine).

What does Cipher doFinal do in Java?

This method returns a byte array containing the encrypted or decrypted message. The doFinal() method also resets the Cipher object to the state it was in when previously initialized via a call to init() method, making the Cipher object available to encrypt or decrypt additional messages.

What is Cipher getInstance?

This class provides the functionality of a cryptographic cipher for encryption and decryption. It forms the core of the Java Cryptographic Extension (JCE) framework. In order to create a Cipher object, the application calls the Cipher's getInstance method, and passes the name of the requested transformation to it.


4 Answers

No, it isn't. The instance is stateful. So you need to store it threadlocal, or to obtain a new instance on every encrypt/decrypt call, or to wrap it in a synchronized(cipher) block.

Threadsafety is usually mentioned in javadocs as "is thread safe" or "is not thread safe". This is not the case for Cipher, so you should not assume it to be threadsafe.

like image 123
BalusC Avatar answered Oct 02 '22 22:10

BalusC


Even if a Cipher was thread-safe, it would not really be useful to use it from multiple threads concurrently.

The bytes you put into and get out of the Cipher (via its update and finish methods) are a continuous stream. This means, on the other end, they have to be passed in the same order to make any sense. This is easiest to accomplish if you have only one thread doing this.

If you are using multiple threads, you usually would want to call reset between the calls - and then you will need external synchronization anyways.

like image 24
Paŭlo Ebermann Avatar answered Oct 02 '22 20:10

Paŭlo Ebermann


I wouldn't use Cipher objects from multiple threads without synchronization. When you look at the API, there are methods which can only work by changing internal state, such as init() and update(). That makes them implicitly non-thread-safe.

like image 43
ddso Avatar answered Oct 02 '22 20:10

ddso


Cipher is not thread safe.

If you use multithreading for performance and don't want to do synchronization, you can use Jasypt (http://www.jasypt.org/general-usage.html) it has pooled encryptors: PooledPBEByteEncryptor, PooledPBEStringEncryptor.

If synchronization is ok for you and you use Spring. You can use Encryptors (https://docs.spring.io/spring-security/site/docs/4.2.5.RELEASE/apidocs/org/springframework/security/crypto/encrypt/Encryptors.html). They do synchronization internally to access Cipher.

like image 29
Anton Yuriev Avatar answered Oct 02 '22 20:10

Anton Yuriev