javaencryptionencryption-asymmetricjce

Java Crypto Api - how to choose a cipher provider


In order to implement encryption using Java, I am using JCE, which is nice and fun. I was told that it is better to choose the crypto provider than to use a default one.

I need to choose providers both for symmetric key generation. used by this code (using AES in CBC mode):

 Key sharedKey = (KeyGenerator.getInstance("AES/CBC/PKCS5PADDING", PROVIDER1).generateKey();

And for Asymmetric text encryption used by this code (using RSA in ECB mode):

Cipher rsaEncryptor = Cipher.getInstance("RSA/ECB/PKCS1Padding",PROVIDER2); 

My question is how should I choose PROVIDER1 and PROVIDER2?

for example, I saw that "SunJCE" is a well documented provider, but I don't think it is a "good enough" reason to choose it.

anyone?


Solution

  • In general, you should stick to the default provider, unless there is a compelling reason not to. Hard coding your provider has the serious drawback that your code won't allow you to change your provider without rewriting your code.

    The only reason I would see for choosing a provider directly is to make sure that some security constraints are met, that would not be present for other providers. This is for instance the case if the implementation needs to be FIPS or Common Criteria certified. In practice this may however also be achieved using delayed provider selection.


    The following paragraph is directly from the Oracle documentation:

    Reminder: Cryptographic implementations in the JDK are distributed through several different providers ("Sun", "SunJSSE", "SunJCE", "SunRsaSign") for both historical reasons and by the types of services provided. General purpose applications SHOULD NOT request cryptographic services from specific providers. That is:

    getInstance("...", "SunJCE");  // not recommended
        vs.
    getInstance("...");            // recommended
    

    You can still manage to allow other providers to be used by giving them a higher priority (a lower priority indicator, 1 is highest priority) within the java.security file within the jre/lib/security path of your runtime.

    Java nowadays also use delayed provider selection through the use of specific Key derived classes. If the Oracle provider doesn't recognize the class used then it will check if another registered provider should be used, even if it has lower priority. This means for instance that a reference to a private key, where the actual key is stored within a specific key store, can be handled by the correct provider. This could be the case for e.g. private keys stored in a smart card, HSM, or device specific (Android) keystore.


    If, after all this, you still want to specify the provider using getInstance("Algorithm", "Provider") it might be a good idea to make the provider string configurable (e.g. using properties and using myConfig.getProperty("Provider")). This will allow you to switch to another provider without having to change the code.

    On the other hand, you may want to make sure that this configuration file is protected / signed. In that case it requires an additional level of security.