junit java.security.NoSuchAlgorithmException:找不到任何支持

junit java.security.NoSuchAlgorithmException:找不到任何支持,java,eclipse,encryption,Java,Eclipse,Encryption,我将JUnit4[C:\eclipse\plugins\org.JUnit_4.11.0.V20130308030\JUnit.jar]与eclipse(MARS,版本:MARS Milestone 3(4.5.0M3))结合使用,构建id:20141113-0320 我做了一些测试,测试一个简单的类,效果很好。但现在我想测试我的加密类,它实现了以下加密功能: public String encrypt(String data) { try { SecretKeySp

我将JUnit4[C:\eclipse\plugins\org.JUnit_4.11.0.V20130308030\JUnit.jar]与eclipse(MARS,版本:MARS Milestone 3(4.5.0M3))结合使用,构建id:20141113-0320

我做了一些测试,测试一个简单的类,效果很好。但现在我想测试我的加密类,它实现了以下加密功能:

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工作。我犯了什么明显的错误?

问题在于is行:

Cipher cipher = Cipher.getInstance("Blowfish/CBC/ZeroBytePadding");
您请求的算法在您的系统上不受支持。您需要该算法的具体原因是什么

指定以下默认实现:

  • AES/CBC/NOP(128)
  • AES/CBC/PKCS5P(128)
  • AES/ECB/NOP(128)
  • AES/ECB/PKCS5P(128)
  • DES/CBC/NOP(56)
  • DES/CBC/PKCS5添加(56)
  • DES/ECB/NOP(56)
  • DES/ECB/PKCS5添加(56)
  • DESede/CBC/NoPadding(168)
  • DESede/CBC/PKCS5添加(168)
  • DESede/ECB/NoPadding(168)
  • DESede/ECB/PKCS5新增(168)
  • RSA/ECB/PKCS1P(10242048)
  • RSA/ECB/OAEPHA-1和MGF1padding(10242048)
  • RSA/ECB/OAEPHA-256和MGF1填充(10242048)

您需要将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
在运行时的类路径中,然后才能安装提供程序。

注意:Bouncy Castle的零字节填充始终应用,例如,对于Blowfish为1..8字节,这与mcrypt(在PHP中)执行的零字节填充不同,即0..7字节。如果你想模拟这种填充,你需要自己填充。嗨,owlstead,这看起来像是一个有用的提示,我将研究这个BC prov。奇怪的是,只有JUnit给了我一个问题。为什么你认为只有JUnit不适合Blowfish/ZeroBytePadding?为什么我的Java和Java PHP很好?但是谢谢,我将测试BCprov,让您知道它是如何改进的。它不是JUnit,这是因为在特定的运行时配置中,提供程序未安装或在类路径中丢失。您始终可以通过从
安全性
类请求提供程序列表进行测试。检查您是否使用了正确的JRE,有时我会发现使用了完全不同的JRE。感谢Rick的回复。这是一个有趣的观察结果。正如您所看到的,我有一个注释“//PKCS5Padding”。我将其更改为ZeroBytePadding,因为这将使我的代码与PHP端的填充类型保持一致。从Blowfish实现中,我观察到我可以使用它。但从形式上说,你是对的,它没有出现在文档中。但是现在,对于一百万美元的问题(顺便说一句,我不会把它作为奖励)…这在我的Java和Java PHP中究竟是如何工作的,并且只有在使用JUnit时才会失败?有什么想法吗?有人吗?请看@owlsetad的答案。他提供了一些关于安装提供程序的说明。但是,这与JUnit无关。如果您只需创建一个
main
方法并尝试使用
encrypt
,您将运行到JUnit他遇到了同样的问题。