我有这个密码学类。解密方法返回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