我有這個密碼學類。解密方法返回null
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Crypto
{
public Crypto(){
}
public static void main(String args[]){
Crypto crypto = new Crypto();
byte encrypted[] = crypto.encrypt("test encryption");
System.out.println(encrypted);
String decrypted = crypto.decrypt(encrypted);
System.out.println(decrypted);
}
public byte[] encrypt(String input){
try{
Crypto crypto = new Crypto();
SecretKeySpec key = crypto.hashPhrase();
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.ENCRYPT_MODE, key);
return aes.doFinal(input.getBytes());
}
catch(Exception e){
return null;
}
}
public SecretKeySpec hashPhrase(){
try{
String code = "some code";
MessageDigest digest = MessageDigest.getInstance("SHA");
digest.update(code.getBytes());
return new SecretKeySpec(digest.digest(), 0, 16, "AES");
}
catch(Exception e){
return null;
}
}
public String decrypt(byte[] input){
try{
Crypto crypto = new Crypto();
SecretKeySpec key = crypto.hashPhrase();
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, key);
return new String(aes.doFinal(input));
}
catch(Exception e){
return null;
}
}
}
當我在這個類中運行main時,它工作正常。我看到一個加密值,然後在解密方法被調用後,我看到原始輸入 - 「測試加密」。
但是,當我嘗試實際使用解密方法時,遇到問題。我已經縮短了這個課程,只展示了相關的部分。
public void read() throws java.io.IOException{
Crypto crypto = new Crypto();
byte[] input;
BufferedReader in = new BufferedReader(new FileReader("C:\\Budget\\data.txt"));
while(in.ready()) {
input = in.readLine().getBytes();
BudgetInterface.list.add(crypto.decrypt(input)); //ArrayList of Objects
System.out.println(crypto.decrypt(input));
//BudgetInterface.list.add(in.readLine()); - artifact from version without cryptographic capability
}
in.close();
}
BudgetInterface.list是對象的ArrayList,如前所述,並且我試圖輸入的解密版本添加到數組,但crypto.decrypt(輸入)返回在每一行文件。如果我刪除加密元素,它可以從文件中讀取沒有問題的行。如果我不嘗試解密,它也讀取得很好。爲什麼解密方法在此方法中返回null,但Crypto類的主要方法中沒有?
編輯:獲得堆棧跟蹤後,我得到的錯誤是javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
我明白這是什麼話,但如何走到這一步,只有當我得到的東西從一個加密的文件,會發生什麼?我從文件中讀取的字節數組和我從Crypto中的主要方法獲得的字節數組長度相同。
停止捕獲異常,吞下它們並返回'null',你可能會發現什麼地方出錯了。 *至少*將日誌記錄添加到您的catch塊中,理想情況下可以捕獲更具體的異常,並且最好不要捕獲它們,但讓它們冒泡到更高級別的代碼。哦,不要使用無參數的'String.getBytes()'或者'String(byte [])'構造函數 - 總是指定一個編碼。 –
得到一個堆棧跟蹤,並添加了一個編輯到頂層的帖子,這並沒有多大幫助。文件中的字節數組和主函數生成的字節數組長度相同。 – Lighthat
'FileReader'也使用默認的字符編碼,因爲你不能指定你自己的,所以它已經(或應該)半贊成包裝在'InputStreamReader'中的'FileInputStream'。 (FYI @JonSkeet) – ntoskrnl