我已经使用代码来解密用Java mcrypt
函数加密的Java文件。
private String iv = "MYKEYHERE";//Dummy iv (CHANGE IT!)
private String SecretKey = "MYKEYHERE";//Dummy secretKey (CHANGE IT!)
private byte[] decrypt(String code)
{
byte[] decrypted = null;
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
SecretKeySpec keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
if(code == null || code.length() == 0)
throw new Exception("Empty string");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e) {
e.printStackTrace();
}
return decrypted;
}
private static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
try {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return buffer;
}
}
我正在从SDCARD读取和写入文件
String encyptedData = readFileFromSDCard(params[0]);
byte[] decryptedByteArray = decrypt(encyptedData);
File rootFile = new File(Constants.folioTempLocation+params[1]);
rootFile.mkdirs();
File outFile = new File(rootFile, new File(params[0]).getName());
FileOutputStream out = new FileOutputStream(outFile);
//IOUtils.write(decryptedByteArray, out);
out.write(decryptedByteArray);
out.flush();
out.close();
解密并将文件写回SD_CARD没有问题。但是我在每个文件的末尾加上未知字符,这限制了整个解密文件的正常运行。
我附加了连接到字符串结尾的未知字符的屏幕截图。我还为想要使用此文件测试代码的任何人附加encrypted_html_file。
截图
答案 0 :(得分:3)
CBC是一种阻止模式,必须使用适当的填充方案。
PHP的mcrypt使用zero padding - 它将\0
个字符附加到输入数据,使其长度为块大小的倍数。显然,你在解密时会得到这些零字节。
mycrypt页面提供了一个如何在用户注释中实现正确的PKCS#7填充方案的示例。其他mcrypt padding个问题How to add/remove PKCS7 padding from an AES encrypted string?提供了类似的示例。
答案 1 :(得分:0)
由于我不知道问题的原因,我只能提供一种解决方法来删除尾随空值(NUL)。
public static byte[] removeTrailingNulls(byte[] source) {
int i = source.length;
while (source[i - 1] == 0x00) {
i--;
}
byte[] result = new byte[i];
System.arraycopy(source, 0, result, 0, i);
return result;
}
在解密文件后立即尝试
byte[] decryptedByteArray = removeTrailingNulls(decrypt(encyptedData));
警告: 这可能会影响性能(特别是在移动设备上),因为它几乎占用了两倍的内存使用量。
此解决方法并不完美,因为它始终会删除尾随空值,无论原始数据如何。使用风险自负