我需要有关此错误的帮助:给定最终块未正确填充。从标题中可以看出,我正在使用AES。
以下是错误的行代码:
byte[] decrypted = cipher.doFinal(bytes);
以下是完整代码:
public class AESCrypt {
private final Cipher cipher;
private final SecretKeySpec key;
private String encryptedText, decryptedText;
public AESCrypt(String password) throws Exception {
// hash password with SHA-256 and crop the output to 128-bit for key
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(password.getBytes("UTF-8"));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
key = new SecretKeySpec(keyBytes, "AES");
}
public String encrypt(String plainText) throws Exception {
byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
AlgorithmParameterSpec spec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
encryptedText = asHex(encrypted);
return encryptedText;
}
public String decrypt(String cryptedText) throws Exception {
byte[] iv = new byte[cipher.getBlockSize()];
AlgorithmParameterSpec spec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
// decrypt the message
byte[] bytes = cryptedText.getBytes("UTF-8");
byte[] decrypted = cipher.doFinal(bytes);
decryptedText = asHex(decrypted);
System.out.println("Desifrovani tekst: " + decryptedText + "\n");
return decryptedText;
}
public static String asHex(byte buf[]) {
StringBuilder strbuf = new StringBuilder(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String[] args) throws Exception {
System.out.print("....AES....\n");
String message = "MESSAGE";
String password = "PASSWORD";
System.out.println("MSG:" + message);
AESCrypt aes = new AESCrypt(password);
String encryptedText = aes.encrypt(message).toString();
System.out.println("SIFROVANA PORUKA: " + encryptedText);
String decryptedText = aes.decrypt(encryptedText).toString();
System.out.print("DESIFROVANA PORUKA: " + decryptedText);
}
}
答案 0 :(得分:3)
根据您的评论,您非常接近加密工作。
您需要将IV生成代码从加密/解密方法移动到其他地方,就像这样
public AlgorithmParameterSpec getIV() {
AlgorithmParameterSpec ivspec;
byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
ivspec = new IvParameterSpec(iv);
}
然后将ivspec传递给加密和解密方法(使它们看起来像encrypt(String,AlgorithmParameterSpec)
),这样你就可以使用相同的iv进行加密和解密。
另外,请勿在decryptedByteArray上调用printBase64Binary
,而是调用new String(decryptedByteArray, "UTF-8")
答案 1 :(得分:0)
您有两个问题,首先将输出编码为十六进制字符串,但不要在解码方法中对其进行解码。其次,您生成随机IV,但不要再次使用它进行解码。
public byte[] encrypt(String plainText) throws Exception {
byte[] iv = new byte[cipher.getBlockSize()];
AlgorithmParameterSpec spec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
return cipher.doFinal(plainText.getBytes());
}
public String decrypt(byte[] cryptedText) throws Exception {
byte[] iv = new byte[cipher.getBlockSize()];
AlgorithmParameterSpec spec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
// decrypt the message
byte[] decrypted = cipher.doFinal(cryptedText);
decryptedText = new String(decrypted, "UTF-8");
return decryptedText;
}
String decryptedText = aes.decrypt(aes.encrypt(message)).toString();