解密时出错:javax.crypto.IllegalBlockSizeException:使用填充密码解密时,输入长度必须是8的倍数

时间:2014-04-07 21:36:28

标签: java encryption cryptography byte des

这是使用DES进行加密和解密的程序。程序在直接传递加密输出以进行解密时正在工作。但是当从字符串中的用户获取输入进行解密时,它会显示此异常。如何以字节为单位传递密码字符串,使其与解密兼容?

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.xml.bind.DatatypeConverter;
public class DESEncryptionDecryption {

private static Cipher encryptCipher;
private static Cipher decryptCipher;

public static void main(String[] args) throws InvalidKeySpecException {
try {

String desKey = "0123456789abcdef"; // value from user
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
System.out.println(keyBytes);

SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));

encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedData = encryptData("Confidential data"); //String from user

String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();

decryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
decryptData(bb); //Exception

}catch (NoSuchAlgorithmException e) {
       e.printStackTrace();
      } catch (NoSuchPaddingException e) {
       e.printStackTrace();
      } catch (InvalidKeyException e) {
       e.printStackTrace();
      } catch (IllegalBlockSizeException e) {
       e.printStackTrace();
      } catch (BadPaddingException e) {
       e.printStackTrace();
      }}
//method for encryption
private static byte[] encryptData(String data)
       throws IllegalBlockSizeException, BadPaddingException {
      System.out.println("Data Before Encryption :" + data);
      byte[] dataToEncrypt = data.getBytes();
      byte[] encryptedData = encryptCipher.doFinal(dataToEncrypt);
      System.out.println("Encryted Data: " + encryptedData);

      return encryptedData;
     }

//method for decryption

private static void decryptData(byte[] data)
throws IllegalBlockSizeException, BadPaddingException {
byte[] textDecrypted = decryptCipher.doFinal(data); //Exception trigered here
System.out.println("Decryted Data: " + new String(textDecrypted));
}}

1 个答案:

答案 0 :(得分:1)

我不能轻易判断这是否所有这是错误的,但这绝对是错误的:

byte[] encryptedData = encryptData("Confidential data"); //String from user
String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();

只需解密encryptedData而不是bb。您的s值基本上没用,因为您在toString()上调用byte[],这不会给您显示您期望的内容。 s的值类似于"[B@15db9742",因为数组不会覆盖Java中的toString()

如果您确实想将任意二进制数据(例如加密结果)转换为文本,请改用base64。使用base64对加密结果进行编码以获取字符串,然后在字符串中对其进行base64解码,然后解密该字节数组。

哦,我强烈建议不要使用String(byte[])String.getBytes() - 总是使用带有字符编码的重载。