2014-12-02 127 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

相关问题