2014-12-02 65 views
2

我正在使用JUnit 4 [C:\ eclipse \ plugins \ org.junit_4.11.0.v201303080030 \ junit.jar]與Eclipse(MARS,版本: Mars Milestone 3(4.5.0M3)Build ID: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; 
} 

的加密類沒有子歸......

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/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(102 4,2048)
+0

感謝您迴應裏克。這是一個有趣的觀察。正如你所看到的,我有評論'// PKCS5Padding'。我已經將它更改爲ZeroBytePadding,因爲這會將我的代碼與我在PHP端的填充類型對齊。從Blowfish的實現中,我觀察到我可以使用它。但在形式上你是對的,它沒有在文檔中顯示。 但現在的一百萬美元的問題(不會給作爲的方式獎勵)...如何在地球上這項工作在我的Java的Java和Java的PHP和使用JUnit時只有失敗?那裏有任何想法?任何人? – 2014-12-03 06:17:20

+0

請參閱@owlsetad的答案。他提供了有關安裝提供程序的一些說明。但是,這不是JUnit相關的。如果你只是簡單地創建一個'main'方法並嘗試使用'encrypt',你會遇到同樣的問題。 – Rick 2014-12-03 09:56:45

2

您需要將Bouncy Castle提供程序添加到Java運行時。您可以通過查看來了解如何安裝提供程序。 Java安裝不支持Blowfish算法和零填充。

下運行在我的箱子罰款:

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的零字節填充總是被應用*,即Blowfish的1..8個字節,這與例如不同。由mcrypt執行的零字節填充(以PHP爲單位),即0..7個字節。如果你想模仿這種填充,你需要填充自己。 – 2014-12-02 23:03:26

+0

嗨,貓頭鷹,這看起來像一個有用的提示,我會研究這個BC-prov。奇怪的是,只有JUnit給我一個問題。爲什麼你認爲只有JUnit對於Blowfish/ZeroBytePadding不好?爲什麼我的Java-Java和Java-PHP很好?但是,謝謝你,我會測試BCprov,讓你知道如何改善事情。 – 2014-12-03 06:25:44

+0

這不是JUnit,這是因爲在特定的運行時配置中,沒有安裝或缺少類路徑中的提供程序。你總是可以通過請求'Security'類的提供者列表來測試。檢查你使用的是正確的JRE,有時我發現使用了完全不同的JRE。 – 2014-12-03 08:45:33

相關問題