美好的一天。我正在製作一個Java程序,它將讀取一個加密文件,並在密鑰的幫助下解密它。我使用這個AES Encryption算法,因爲它提供了我也需要的代碼。Java AES解密 - 給定最終塊未正確填充錯誤
我所做的是將Java Class複製到我的項目中。這就是我的AES.java
文件看起來像:
public class AES{
private static SecretKeySpec secretKey ;
private static byte[] key ;
private static String decryptedString;
private static String encryptedString;
public static void setKey(String myKey){
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
System.out.println(key.length);
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
System.out.println(key.length);
System.out.println(new String(key,"UTF-8"));
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getDecryptedString() {
return decryptedString;
}
public static void setDecryptedString(String decryptedString) {
AES.decryptedString = decryptedString;
}
public static String getEncryptedString() {
return encryptedString;
}
public static void setEncryptedString(String encryptedString) {
AES.encryptedString = encryptedString;
}
public static String encrypt(String strToEncrypt){
try{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
// byte[] encodedBytes = Base64.getEncoder().encode(strToEncrypt.getBytes("UTF-8"));
// setEncryptedString(new String(encodedBytes));
}
catch (Exception e)
{
System.out.println("Error while encrypting: "+e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt){
try{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));
//setDecryptedString(new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))));
}
catch (Exception e){
System.out.println("Error while decrypting: "+e.toString());
}
return null;
}
public static void main(String args[]){
final String strToEncrypt = "My text to encrypt";
final String strPssword = "encryptor key";
AES.setKey(strPssword);
AES.encrypt(strToEncrypt.trim());
System.out.println("String to Encrypt: " + strToEncrypt);
System.out.println("Encrypted: " + AES.getEncryptedString());
final String strToDecrypt = AES.getEncryptedString();
AES.decrypt(strToDecrypt.trim());
System.out.println("String To Decrypt : " + strToDecrypt);
System.out.println("Decrypted : " + AES.getDecryptedString());
}
}
在我Main.java
類:我有以下幾點:我的文件
//I get my encoded input as a FileInputStream
InputStream encodedInput = null;
encodedInput = new FileInputStream("./Config/config2.properties");
//get the input and then convert to Bytes then to String
//I also tried converting to String right away
byte[] inputBytes = IOUtils.toByteArray(encodedInput);
String theString = IOUtils.toString(inputBytes, "UTF-8"); //IOUtils.toString(encodedInput, "UTF-8");
System.out.println("Input string (encoded) = " + theString);
//It stops at the decrypt call and throw the exception
AES.setKey(localProperties.getKey());
AES.decrypt(theString.trim());
String decrypted = AES.getDecryptedString();
正如你所看到的,得到的內容。內容是正確的,因爲我也在系統日誌中打印它們。
但我不明白爲什麼解密函數不能解密它,即使函數要求輸入一個字符串。
我真的傻眼了,我不知道從哪裏開始。任何幫助將非常感激。
嗯。你的PKCS5PADDING在解密和大寫情況下都是在加密中。我不確定這是否會導致問題,但值得堅持使用PKCS5Padding – slipperyseal
**切勿使用[ECB模式](http://crypto.stackexchange.com/q/14487/13022)**。它是確定性的,因此不具有語義安全性。您至少應該使用[CBC](http://crypto.stackexchange.com/q/22260/13022)或[CTR](http://crypto.stackexchange.com/a/2378/)這樣的隨機模式。 13022)。最好是對密文進行身份驗證,以便像[padding oracle attack](http://crypto.stackexchange.com/q/18185/13022)這樣的攻擊是不可能的。這可以通過驗證模式(如GCM或EAX)或[加密 - 然後MAC](http://crypto.stackexchange.com/q/202/13022)方案完成。 –
如果你的解密有問題,你應該顯示加密。儘管EJP的答案可能有幫助,但我不明白他的答案能夠解決您的問題。 –