我试图加密两个不同文件中的某些信息,第一个用AES加密的字符串,第二个用RSA加密密钥,但我在使用它时遇到了一些麻烦。< / p>
这是我的方法:
public synchronized static void encrypToFile(KeyPair clauPublicaPrivada, SecretKey clauSecretaSimetrica) {
String dades = null;
byte[][] encWrappedData = new byte[2][];
byte[] dadesAEncriptarEnByte;
dades = extreureRutesDB();
dadesAEncriptarEnByte = dades.getBytes();
try {
try {
File file = new File(FITXER_DADES_TRIPULANTS_XIFRADES_AES128);
File file2 = new File(FITXER_DADES_TRIPULANTS_XIFRADES_AES128_CLAUS);
boolean fvar = file.createNewFile();
boolean fvar2 = file2.createNewFile();
if (fvar2) {
System.out.println("File2 has been created successfully");
} else {
System.out.println("File2 already present at the specified location");
}
if (fvar) {
System.out.println("File1 has been created successfully");
} else {
System.out.println("File1 already present at the specified location");
}
} catch (IOException e) {
System.out.println("Exception Occurred:");
e.printStackTrace();
}
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
cipher.init(Cipher.ENCRYPT_MODE, clauSecretaSimetrica, iv);
encWrappedData[0] = cipher.doFinal(dadesAEncriptarEnByte);
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
PublicKey clauPublica = clauPublicaPrivada.getPublic();
cipher.init(Cipher.WRAP_MODE, clauPublica);
encWrappedData[1] = cipher.wrap(clauSecretaSimetrica);
CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(FITXER_DADES_TRIPULANTS_XIFRADES_AES128), cipher);
cos.write(encWrappedData[0]);
cos.close();
cos = new CipherOutputStream(new FileOutputStream(FITXER_DADES_TRIPULANTS_XIFRADES_AES128_CLAUS), cipher);
cos.write(encWrappedData[1]);
cos.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("menu 21(): FINAL");
}
}
问题在于,当我运行它时,我收到此错误:
java.lang.IllegalStateException:未对加密/解密初始化密码
知道我做错了什么以及如何解决它?
答案 0 :(得分:3)
为不同目的重用相同的Cipher
变量是糟糕的编程习惯和混乱,并导致您遇到这些错误。您在致电cipher
之前离开了WRAP_MODE
中的doWrap()
个实例。然后,您向CipherOutputStream
构造函数提供相同的实例。这些要求cipher
对象位于ENCRYPT_MODE
或DECRYPT_MODE
。
只需为Cipher对象的每个不同用途调用Cipher.getInstance()
即可。除非你确实做了一些非常奇怪的事情(并且可能是错误的),否则这个电话的开销在你的节目中是微不足道的。
答案 1 :(得分:1)
您未正确使用CipherOutputStream
值。确切地说,您的代码设置方式根本不需要使用 。这些输出流用于加密和解密数据。
但是,在调用encWrappedData[0] = cipher.doFinal(dadesAEncriptarEnByte);
和encWrappedData[1] = cipher.wrap(clauSecretaSimetrica);
时,数据已经加密。
因此,您只需使用FileOutputStream
即可直接将这些调用的结果写入文件。
RSA包装的AES密钥的大小总是有限的,因此传输该信息没有意义。如果消息(dades
)很大,您可能希望使用流式传输,并使用基于AES的密码实例来执行加密,而不将所有明文和密文都放在内存中的字节数组中。在这种情况下,CipherOutputStream
可能有意义。