【发布时间】:2015-02-16 05:51:23
【问题描述】:
您好,我正在我的项目中进行 AES 加密和解密。
我有一个使用“AES/CBC/pkcs5padding”加密的 .mp4 文件。
我有用于加密音频文件前 256 个字节的密钥和 iv 值。
我需要使用相同的算法、密钥和 iv 值解密文件的前 256 个字节。
我有一个音频播放器演示,并尝试将我的部分(AES 加密和解密)实现为演示。
下面我解释了我所做的代码。
此方法从 res/raw 文件夹下的加密文件中读取数据。
private void readFile() throws IOException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException {
Context context = getApplicationContext();
/*
* InputStream is = getResources().openRawResource(
* getResources().getIdentifier("raw/encrypted", "raw",
* getPackageName())); String text = "";
*
* int size = is.available(); byte[] buffer = new byte[size];
* is.read(buffer);
*/
InputStream inStream = context.getResources().openRawResource(
R.raw.encrypted);
// get string from file
byte[] music = new byte[256];
for (int i = 0; i <= inStream.available(); i = i + 255) {
music = convertStreamToByteArray(inStream, i);
byte[] bytesToWrite = new byte[256];
bytesToWrite = music;
if (i == 0) {
bytesToWrite = AES256Cipher.decrypt(iv.getBytes("UTF-8"),
key.getBytes("UTF-8"), music);
// writeFirstSetOfBytes("decrypted.mp4");
}
writeFirstSetOfBytes(bytesToWrite);
}
}
解密方法来自link1。这里我传递了上面提到的key和iv值。
public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes,
byte[] textBytes) throws java.io.UnsupportedEncodingException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
// SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,
new SecretKeySpec(keyBytes, "AES"), ivSpec);
return cipher.doFinal(textBytes);
}
此方法用于从输入流中获取字节数组。
public static byte[] convertStreamToByteArray(InputStream is, int size)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[256];
int i = Integer.MAX_VALUE;
while ((i = is.read(buff, size, buff.length)) > 0) {
baos.write(buff, 0, i);
}
return baos.toByteArray(); // be sure to close InputStream in calling
// function
}
此方法将接收到的字节数组写入目标文件(decrypted.mp4)
private void writeFirstSetOfBytes(byte[] byteToWrite) {
File file = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"/decrypted.mp4");
FileOutputStream stream = null;
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// writing data into file
try {
stream = new FileOutputStream(file);
stream.write(byteToWrite);
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我收到以下错误。
javax.crypto.IllegalBlockSizeException: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
我怎样才能达到我的要求?
- 如何只解密前 256 个字节的数据?
- 是否有任何代码行为错误?
- 是否有可用的第三方库?
如果需要更多说明,请告诉我。
【问题讨论】:
-
只是一个旁注。
decrypt()例程需要iv和key作为原始字节,但您的readFile()例程似乎将它们从某些文本表示形式转换。你确定你没有传递十六进制字符串而不是原始字节吗? -
我真的不知道从哪里开始。您的流处理完全不正确 - 包括两个循环,您使用的是
i = i + 255,CBC 模式可能不是一个好主意。
标签: android cryptography aes