1

I'm working on Java 1.7 - Window 7 (64 bit). I want to get SecretKeyFactory instance and Cipher instance of PBEWithHmacSHA256AndDESede algorithm. Unfortunately, I only got exceptions

java.security.NoSuchAlgorithmException: Cannot find any provider supporting PBEWithHmacSHA256AndDESede
at javax.crypto.Cipher.getInstance(Cipher.java:524)

Can you share me your solution of this problem?

Ken Block
  • 3,423
  • 1
  • 21
  • 23

4 Answers4

4

The solution to this problem is two-part:

First, you need to call SecretKeyFactory.getInstance("PBEWithHmacSHA256AndDESede") instead of Cipher.getInstance("PBEWithHmacSHA256AndDESede"), as indicated by your stacktrace.

Second, you need to find the security provider that supports that algorithm. Neither SunJCE no BC 1.50 support it, by the way, so you will have to search for more exotic variants.

You can use the following code to check all installed providers and SecretKeyFactory algorithms supported by them:

// Security.addProvider( new BouncyCastleProvider() );
for ( Provider provider : Security.getProviders() ) {
    System.out.println( provider );
    for ( Provider.Service service : provider.getServices() ) {
        if ( "SecretKeyFactory".equals( service.getType() ) ) {
            System.out.println( service );
        }
    }
}

BC 1.50 definitely supports PBE with SHA-256 and AES variants under the names PBEWITHSHA256AND128BITAES-CBC-BC (OID 1.3.6.1.4.1.22554.1.2.1.2.1.2), PBEWITHSHA256AND192BITAES-CBC-BC (OID 1.3.6.1.4.1.22554.1.2.1.2.1.22) and PBEWITHSHA256AND256BITAES-CBC-BC (OID 1.3.6.1.4.1.22554.1.2.1.2.1.42).

It also supports a SecretKeyFactory algorithm with the name PBEWITHHMACSHA256 and OID 2.16.840.1.101.3.4.2.1, but that OID designates the plain SHA-256 hash function, meaning that this secret factory will use only hash instead of hash+cipher.

Oleg Estekhin
  • 8,063
  • 5
  • 49
  • 52
  • just had to add the bouncycastleprovider for me to get it to work, thanks! – William Reed May 24 '18 at 01:45
  • The PBE...-BC schemes are instances of the PKCS12 appendix B&C PBE, which do not use HMAC, and those instances don't use DESede aka 3DES/TDES/TDEA either. In spite of the name 'PBEWITHHMACSHA256' is actually a MAC scheme, specifically the PKCS12 PBMAC scheme, not PBE at all; it uses plain hash in the key derivation, but HMAC for the resulting MAC. – dave_thompson_085 Jan 23 '19 at 00:00
1

Have you:

user3465651
  • 706
  • 1
  • 4
  • 22
  • How can I check my security providers support 'PBEWithHmacSHA256AndDESede'. All available providers are in java.security: sun.security.provider.Sun sun.security.rsa.SunRsaSign sun.security.ec.SunEC com.sun.net.ssl.internal.ssl.Provider com.sun.crypto.provider.SunJCE sun.security.jgss.SunProvider com.sun.security.sasl.Provider org.jcp.xml.dsig.internal.dom.XMLDSigRI sun.security.smartcardio.SunPCSC sun.security.mscapi.SunMSCAPI. Are providers loaded automatically or only loaded with special argument at runtime? – Ken Block Jul 01 '14 at 08:26
  • 1
    Looking at the docs on Oracle site, seems the SHA256 is not supported in the default SUN security provider for SecretKeyFactory. Only MD5 and SHA1. http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html . Bounceycastle a similar story, https://www.bouncycastle.org/specifications.html (search for 'Defined in Bouncy Castle JCE Provider' on the page – user3465651 Jul 01 '14 at 08:41
0

As @user3465651 points out, you have to have a library that supports this, such as BouncyCastle. In my case the error was:

java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available

In troubleshooting, you can explicitly specify the library that contains the algorithm this way:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");

If you've done that you may still get this error if you're using Maven's shade plugin:

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC

The shade plugin breaks the the cryptographic signature (explanation).

You can instead use the executable packer maven plugin solution that uses a jar-in-jar approach which preserves the signature for JCE in a single, executable jar.

MattW
  • 783
  • 7
  • 11
-1

Try this:

Old code:

String passphrase = "test";
KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
...
ecipher.init(Cipher.ENCRYPT_MODE, ket, paramSpec);
...

New Code :

String passphrase = "test";
KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance("PBEWithMD5AndDES");
...
ecipher.init(Cipher.ENCRYPT_MODE, ket, paramSpec);
wahwahwah
  • 3,254
  • 1
  • 21
  • 40
  • 1
    Hi! Welcome to SO! Please take a look at the help section of the site on [how to answer](http://stackoverflow.com/help/how-to-answer). While brief answers are totally acceptable, better answers typically include some written context to why the answer is applicable. Best. – wahwahwah Jun 03 '15 at 17:41