AES Bouncy Castle-传递给AES init的无效参数 - org.bouncycastle.crypto.params.ParametersWithIV

时间:2017-11-06 19:00:22

标签: java security encryption aes bouncycastle

我正在尝试使用Bouncy城​​堡进行加密和解密。我收到了以下错误。如何修复或有更好的方法来加密和解密使用Bouncy城​​堡

  

线程“main”中的异常java.security.InvalidKeyException:传递给AES init的无效参数 - org.bouncycastle.crypto.params.ParametersWithIV       at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(Unknown Source)       在javax.crypto.Cipher.init(Cipher.java:1394)       在com.test.PBE.encrypt(PBE.java:39)       在com.test.PBE.main(PBE.java:26)

这是我的代码

import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class PBE {

private static final String salt = "A long, but constant phrase that will be used each time as the salt.";
private static final int iterations = 2000;
private static final int keyLength = 256;
private static final SecureRandom random = new SecureRandom();

public static void main(String [] args) throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);

    String passphrase = "The quick brown fox jumped over the lazy brown dog";
    String plaintext = "hello world";
    byte [] ciphertext = encrypt(passphrase, plaintext);
    String encryptedText=ciphertext.toString();
    System.out.println("text::"+encryptedText);

    String recoveredPlaintext = decrypt(passphrase, encryptedText);

    System.out.println(recoveredPlaintext);
}

private static byte [] encrypt(String passphrase, String plaintext) throws Exception {
    SecretKey key = generateKey(passphrase);

    Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
    cipher.init(Cipher.ENCRYPT_MODE, key, generateIV(cipher), random);
    return cipher.doFinal(plaintext.getBytes());
}

private static String decrypt(String passphrase, String encryptedText) throws Exception {
    byte[] ciphertext=encryptedText.getBytes();
    SecretKey key = generateKey(passphrase);

    Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
    cipher.init(Cipher.DECRYPT_MODE, key, generateIV(cipher), random);
    return new String(cipher.doFinal(ciphertext));
}

private static SecretKey generateKey(String passphrase) throws Exception {
    PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(), iterations, keyLength);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
    return keyFactory.generateSecret(keySpec);
}

private static IvParameterSpec generateIV(Cipher cipher) throws Exception {
    byte [] ivBytes = new byte[cipher.getBlockSize()];
    random.nextBytes(ivBytes);
    return new IvParameterSpec(ivBytes);
}

}

1 个答案:

答案 0 :(得分:0)

重要的是要理解加密的结果是二进制数据,并且不能将其视为文本。

如果要将加密数据转换为文本,则应对其进行十六进制编码,例如使用this one from apache commons等库。在大多数情况下,永远不必使用加密数据的文本版本。

特别是,你通过插入字符串转换字节数组的方式肯定不能达到预期目的。

根据您的代码,您需要更改decrypt方法以获取byte[]并将byte[] encryptedtext传递给它。