简体   繁体   English

密码线程安全吗?

[英]Is Cipher thread-safe?

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

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.所以你需要将它存储在线程本地,或者在每次加密/解密调用时获取一个新实例,或者将它包装在一个synchronized(cipher)块中。

Threadsafety is usually mentioned in javadocs as " is thread safe " or " is not thread safe ". 线程安全通常在 javadocs 中被称为“ 是线程安全的”或“ 不是线程安全的”。 This is not the case for Cipher , so you should not assume it to be threadsafe.这不是Cipher的情况,所以你不应该假设它是线程安全的。

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.您放入和从 Cipher 中取出的字节(通过它的updatefinish方法)是一个连续的流。 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.如果您使用多个线程,您通常希望在调用之间调用reset - 然后无论如何您都需要外部同步。

I wouldn't use Cipher objects from multiple threads without synchronization.我不会在没有同步的情况下使用来自多个线程的 Cipher 对象。 When you look at the API, there are methods which can only work by changing internal state, such as init() and update() .当您查看 API 时,有些方法只能通过更改内部状态来工作,例如init()update() That makes them implicitly non-thread-safe.这使它们隐式地非线程安全。

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

If synchronization is ok for you and you use Spring.如果同步适合您并且您使用 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 ).您可以使用加密器( 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.他们在内部进行同步以访问 Cipher。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM