簡単に言えば、_javax.crypto.Cipher
_の1つのインスタンス(たとえばCipher.getInstance("RSA")
)を複数のスレッドから使用できますか、またはそれらの複数をThreadLocal
に固定する必要がありますか(私の場合)。 ?
いいえ、そうではありません。インスタンスはステートフルです。したがって、それをスレッドローカルに保存するか、すべての暗号化/復号化呼び出しで新しいインスタンスを取得するか、synchronized(cipher)
ブロックでラップする必要があります。
スレッドセーフは通常、javadocで言及されている explicitly です。これは Cipher
の場合ではないため、スレッドセーフであると想定しないでください。
Cipherがスレッドセーフであったとしても、複数のスレッドから同時にそれを使用することは実際には役に立ちません。
(update
およびfinish
メソッドを介して)Cipherに出し入れするバイトは、連続したストリームです。つまり、反対側では、意味をなすために同じ順序で渡す必要があります。これを行うスレッドが1つしかない場合、これは最も簡単に実行できます。
複数のスレッドを使用している場合は、通常、呼び出しの間にreset
を呼び出す必要があります-とにかく外部同期が必要になります。
同期せずに複数のスレッドのCipherオブジェクトを使用しません。 APIを見ると、init()
やupdate()
など、内部状態を変更することによってのみ機能するメソッドがあります。これにより、暗黙的にスレッドセーフではなくなります。
暗号はスレッドセーフではありません。
パフォーマンスのためにマルチスレッドを使用し、同期を行いたくない場合は、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にアクセスするために内部で同期を行います。