Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

junit java.security.NoSuchAlgorithmException: Cannot find any provider supporting

I'm using JUnit 4 [C:\eclipse\plugins\org.junit_4.11.0.v201303080030\junit.jar] in combination with Eclipse (MARS, Version: Mars Milestone 3 (4.5.0M3) Build id: 20141113-0320.

I have some tests that test a simple class and which work well. But now arrived at the point where I wanted to test my encryption class, which implements the following encrypt function:

public String encrypt(String data) {

    try {

        SecretKeySpec KS = new SecretKeySpec(mKeyData, "Blowfish");

        Cipher cipher = Cipher.getInstance("Blowfish/CBC/ZeroBytePadding"); // PKCS5Padding
        cipher.init(Cipher.ENCRYPT_MODE, KS, new IvParameterSpec(mIv));
        return bytesToHex(cipher.doFinal(data.getBytes()));       

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return null;
}

The Crypto class is not sub classed...

public class Crypto {

So to test this Class and more the encrypt function I have designed the following unit test:

package my.junit4.example;

import static org.junit.Assert.*;

import org.junit.Test;

public class CryptoTest {

    @Test
    public void testEncryption() {

        Crypto myCrypto = new Crypto();

        String encodedString = myCrypto.encrypt("Secret");

        assertTrue("The decrypted encrypted word should deliver the original string", encodedString.equals(myCrypto.decrypt(encodedString)));
    }
}

This test is failing with a stack trace:

java.security.NoSuchAlgorithmException: Cannot find any provider supporting Blowfish/CBC/ZeroBytePaddingnull
at javax.crypto.Cipher.getInstance(Cipher.java:535)     at
my.junit.example.encrypt(Crypto.java:35)    at
my.junit.example.CryptoTest.testEncrypt(CryptoTest.java:14)     at

This didn't make much sense to me. But being relatively new to JUnit I suspect the issue is with me not understanding how to formulate these tests. The code works well encryption - decryption in my debugger is giving me the desired outcome. But how can I get this to work with JUnit. What obvious mistake I have made?

like image 406
Toon Leijtens Avatar asked Jan 18 '26 15:01

Toon Leijtens


2 Answers

The problem is with this line:

Cipher cipher = Cipher.getInstance("Blowfish/CBC/ZeroBytePadding");

The algorithm you're requesting is not supported on your system. Any particular reason you want that specific one?

The docs specify the following default implementations:

  • AES/CBC/NoPadding (128)
  • AES/CBC/PKCS5Padding (128)
  • AES/ECB/NoPadding (128)
  • AES/ECB/PKCS5Padding (128)
  • DES/CBC/NoPadding (56)
  • DES/CBC/PKCS5Padding (56)
  • DES/ECB/NoPadding (56)
  • DES/ECB/PKCS5Padding (56)
  • DESede/CBC/NoPadding (168)
  • DESede/CBC/PKCS5Padding (168)
  • DESede/ECB/NoPadding (168)
  • DESede/ECB/PKCS5Padding (168)
  • RSA/ECB/PKCS1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
like image 52
Rick Avatar answered Jan 20 '26 03:01

Rick


You need to add the Bouncy Castle provider to the Java runtime. You can see how to install the provider by looking at the Bouncy Castle wiki page. Neither the Blowfish algorithm nor zero padding is supported out of the box by Java installations.

The following runs fine on my box:

Security.addProvider(new BouncyCastleProvider());

byte[] mKeyData = new byte[16];
byte[] mIv = new byte[8];

SecretKeySpec KS = new SecretKeySpec(mKeyData, "Blowfish");

Cipher cipher = Cipher.getInstance("Blowfish/CBC/ZeroBytePadding");
cipher.init(Cipher.ENCRYPT_MODE, KS, new IvParameterSpec(mIv));

Make sure that the provider is also available to the test framework when it is run. You'll need to put the bcprov-jdk15on-[version].jar in the class path of the runtime before you can install the provider.

like image 24
Maarten Bodewes Avatar answered Jan 20 '26 03:01

Maarten Bodewes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!