Let's talk a bit about concurrency in CryptoAPI. When calling CryptoAPI from different threads, we have to take into consideration that key handles are not thread safe.
The following document describes the threading issues when dealing with key handles in applications: Threading Issues with Cryptographic Service Providers.
Imagine that you have developed an application which creates a session key on startup. The handles to the CSP and session key are stored globally.
According to previous article, the status of the key may be important:
Most algorithms and modes require that data be decrypted in the same order that it was encrypted. This is a difficult task in a multithreaded environment because use of a critical section will not address the ordering issue. If you are using a block cipher (that is, RC2, DES, or 3DES) in ECB cipher mode, then this issue is not a factor because the internal key state does not change. However, ECB is not the default cipher mode. CBC is the default cipher mode. With CBC cipher mode, the internal key state does change.
For instance, when CryptEncrypt/CryptDecrypt is used with the value TRUE for the Final flag, the HCRYPTKEY is actually finalized and shouldn’t be used again.
So when you encrypt/decrypt data you can use a duplicated local HCRYPTKEY handle to perform the operation. You can duplicate the global HCRYPTKEY handle by calling CryptDuplicateKey API. Global HCRYPTKEY will remain in its initial state. Make sure that you call CryptDestroyKey on the local handle. This is Microsoft’s recommended approach.
I hope this helps.
Alex (Alejandro Campos Magencio)