【发布时间】:2013-10-24 14:39:35
【问题描述】:
我有一个要加密的文件 (mp3),然后我打算将此文件下载到 Android 设备并对其进行解密,但在解密过程中我得到一个 IOException:
java.io.IOException: last block incomplete in decryption
我知道以下代码中存在明显的安全漏洞,我只是想先让它工作。
感谢您对此提供的任何帮助,而且我一般是编码新手,所以如果这是一个愚蠢的问题,请提前原谅!
加密类(Android 中没有,可以):
public class EncryptFile {
public static void main(String args[]) {
if (args.length < 1) {
System.out.println("Usage: java EncryptFile <file name>");
System.exit(-1);
}
try {
File aesFile = new File("encodedfile.enc");
FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;
//Creation of Secret key
String key = "mysecretkey";
int length=key.length();
if(length>16 && length!=16){
key=key.substring(0, 15);
}
if(length<16 && length!=16){
for(int i=0;i<16-length;i++){
key=key+"0";
}
}
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES");
//Creation of Cipher objects
Cipher encrypt =Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] aByte = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivSpec = new IvParameterSpec(aByte);
encrypt.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
try {
fis = new FileInputStream(args[0]);
cis = new CipherInputStream(fis,encrypt);
// Write to the Encrypted file
fos = new FileOutputStream(aesFile);
byte[] b = new byte[8];
int i = cis.read(b);
while (i != -1) {
fos.write(b, 0, i);
i = cis.read(b);
}
fos.flush();
fos.close();
cis.close();
fis.close();
} catch(IOException err) {
System.out.println("Cannot open file!");
System.exit(-1);
}
} catch(Exception e){
e.printStackTrace();
}
}
}
解密(在 Android 设备中):
public class DecryptFile {
public static File main(String args[], File encFile, Context context) {
for (int i = 0; i < args.length; i++) {
Log.i("ARGS", args[i]);
}
try {
File aesFile = new File(args[0]);
aesFile= encFile;
Log.d("AESFILELENGTH", "aes length: " + aesFile.length());
File aesFileBis = new File(context.getFilesDir(), args[0]);
FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;
//Creation of Secret key
String key = "mysecretkey";
int length=key.length();
if(length>16 && length!=16){
key=key.substring(0, 15);
}
if(length<16 && length!=16){
for(int i=0;i<16-length;i++){
key=key+"0";
}
}
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES");
//Creation of Cipher objects
Cipher decrypt =Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] aByte = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivSpec = new IvParameterSpec(aByte);
decrypt.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
// Open the Encrypted file
fis = new FileInputStream(aesFile);
cis = new CipherInputStream(fis, decrypt);
// Write to the Decrypted file
fos = new FileOutputStream(aesFileBis);
try {
byte[] mByte = new byte[8];
int i = cis.read(mByte);
Log.i("MBYTE", "mbyte i: " + i);
while (i != -1) {
fos.write(mByte, 0, i);
i = cis.read(mByte);
}
} catch (IOException e) {
e.printStackTrace();
}
fos.flush();
fos.close();
cis.close();
fis.close();
return aesFileBis;
} catch(Exception e){
e.printStackTrace();
}
return null;
}
}
【问题讨论】:
-
检查您正在生成的非 Android 加密文件的长度。将其与您在 Android 中读取的加密文件的长度进行比较。显然,这两个长度应该相同。如果不是,那么您可能有文件传输问题,而不是解密问题。
-
我检查了文件长度,加密文件比原始文件大2个字节,但这是由于填充的原因吗?我还做了一个 byte[] mBytebase = Base64.encodeBase64(key.getBytes());并根据“重复”在我的 SecretKeySpec 中使用它。似乎没有任何帮助
-
如你所说,填充将确保明文和加密文件的长度不同。您需要检查非 Android 和 Android 端的两个 加密 文件的长度是否相同。您需要确保两个系统之间的文件传输不会弄乱数据。
-
啊对,抱歉误解了答案。现在我将加密文件放在资产中进行测试,所以传输不是问题
标签: java android aes encryption