2014-12-02 2 views
2

Я использую JUnit 4 [C: \ eclipse \ plugins \ org.junit_4.11.0.v201303080030 \ junit.jar] в сочетании с Eclipse (MARS, Версия: Mars Milestone 3 (4.5.0M3) Код сборки: 20141113-0320.junit java.security.NoSuchAlgorithmException: Не удается найти провайдера, поддерживающего

У меня есть некоторые тесты, которые проверяют простой класс и которые хорошо работают. Но теперь я пришел к тому моменту, когда хотел проверить свой класс шифрования, который реализует следующая шифровать функция:

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; 
} 

класс Crypto не к югу классифицирован ...

public class Crypto { 

Так, чтобы проверить этот класс и больше функции шифровать я разработал следующий тест блока:

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))); 
    } 
} 

Этот тест неисправного с трассировки стека:

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 

Это не сделать Мне очень нравится. Но, будучи относительно новым для JUnit, я подозреваю, что проблема заключается в том, что я не понимаю, как сформулировать эти тесты. В коде хорошо работает шифрование - дешифрование в моем отладчике дает мне желаемый результат. Но как я могу заставить это работать с JUnit. Какую очевидную ошибку я сделал?

ответ

1

Проблема с этой линии:

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

вы запрашиваете алгоритм не поддерживается в вашей системе. Любая конкретная причина, по которой вы хотите получить эту конкретную?

The docs указать следующие реализации по умолчанию:

  • 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/ТГС/NoPadding (168)
  • DESede/ТГС/PKCS5Padding (168)
  • DESede/ЕЦБ/NoPadding (168)
  • DESede/ЕЦБ/PKCS5Padding (168)
  • RSA/ЕЦБ/PKCS1Padding (1024, 2048)
  • RSA/ЕЦБ/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ЕЦБ/OAEPWithSHA-256AndMGF1Padding (102 4, 2048)
+0

Спасибо, что ответили Риком. Это интересное наблюдение. Как вы можете видеть, у меня был комментарий «// PKCS5Padding». Я изменил это на ZeroBytePadding, так как это приведет к выравниванию моего кода с типом заполнения, которое у меня есть на PHP-конце. Из реализации Blowfish я заметил, что могу ее использовать. Но формально вы правы, что в документах это не было. Но теперь за вопрос на миллион долларов (не будем давать это как награду кстати) ... как это работает в моей Java-Java и Java-PHP и только сбой при использовании JUnit ? Есть идеи? кто угодно? –

+0

См. Ответ от @owlsetad. Он дает некоторые инструкции относительно установки поставщика. Однако это не связано с JUnit. Если вы просто создаете метод 'main' и пытаетесь использовать' encrypt', вы столкнетесь с теми же проблемами. – Rick

2

Вам необходимо добавить поставщика Bouncy Castle в среду выполнения Java. Вы можете посмотреть, как установить поставщика, посмотрев на . Ни алгоритм Blowfish, ни нулевое дополнение не поддерживаются установками Java.

Следующие работает отлично на мой ящик:

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)); 

Убедитесь, что провайдер также доступен для тестовой базы при запуске. Вам нужно будет поместить bcprov-jdk15on-[version].jar в путь класса среды выполнения до того, как вы сможете установить поставщика.

+0

Остерегайтесь: заполнение нулевого байта Bouncy Castle всегда применяется *, то есть 1,8 байт для Blowfish, это отличается от, например, заполнение нулевого байта, выполняемое mcrypt (в PHP), то есть 0..7 байт. Вам нужно будет погрузить себя, если вы хотите подражать подобному заполнению. –

+0

Hi owlstead, это похоже на полезный намек, который я рассмотрю в этом BC-prov. Странно, однако, что только JUnit дает мне проблему. Почему вы думаете, что JUnit не подходит для Blowfish/ZeroBytePadding? и почему мои Java-Java и Java-PHP в порядке? Но спасибо, я все равно проведу BCprov, дайте знать, как это улучшилось. –

+0

Это не JUnit, потому что либо поставщик не установлен, либо отсутствует в пути к классам в этом конкретном контингенте среды выполнения. Вы всегда можете проверить, запросив список поставщиков из класса «Безопасность». Убедитесь, что вы используете правильную JRE, я иногда обнаруживаю, что используется совершенно другая JRE. –

Смежные вопросы