我正在尝试对视频和pdf进行加密。在我获得每个文件的流后,我分成缓冲区,然后我加密每个文件并将所有缓冲区合并为一个加密文件。
对于加密,一切正常,但是当我尝试以相同的方式解密文件时,我在 doFinal 时出现错误
{BadPaddingException:pad块损坏 BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)}
这是我正在测试的代码
加密
public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(fileData);
return encrypted;
}
解密
public static byte[] decodeFile(byte[] key, byte[] fileData)
{
byte[] decrypted=new byte[0];
try {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted= cipher.doFinal(fileData);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
return decrypted;
}
生成密钥
public static byte[] generateKey(String password) throws Exception
{
byte[] keyStart = password.getBytes("UTF-8");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(keyStart);
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
这是我如何解密文件
public void decryptStream(String filePath) {
String outPath = Environment.getExternalStorageDirectory().toString() + "/" + fileName + "de" + "." + fileExtention;
filePath += "_secured." + fileExtention;
byte[] data = new byte[1024];
byte[] decryptData;
File file = new File((filePath));
File deFile = new File(outPath);
InputStream inputStream = null;
try {
inputStream = FileUtils.openInputStream(file);
} catch (IOException e) {
e.printStackTrace();
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream((new FileOutputStream(deFile)));
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte[] decryptByteArray(byte[] input) {
Encryption e=new Encryption();
byte[]decryptedBytes = new byte[0];
try {
byte[] yourKey = e.generateKey("password");
decryptedBytes = e.decodeFile(yourKey, input);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
return decryptedBytes;
}
答案 0 :(得分:1)
问题很可能在这里:
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
当您读取的文件不是1024字节长的倍数时,最后一次读取将不会完全填充字节数组,但您将整个数组传递到decryptByteArray
。
另请注意,即使是中间读取,也无法保证read
将完全填充数组。始终检查返回值,该值给出实际读取的字节数。
问题没有显示加密是如何完成的。如果在密码中使用填充,则1024字节块的每个加密将长于1024字节(因为添加了填充块)。对于解密,必须一次处理整个密文(包括填充)。只使用前1024个字节将导致BadPaddingException
。