我正在使用以下代码加密资产文件夹中的图像并尝试在 apk 中解密。(我这样做只是为了避免通过解压缩apk文件轻松复制图像)。我知道我将把密钥作为 apk 的一部分。
我使用并测试了下面的代码,用于使用独立的 java 程序加密图像。(我通过 decrpyting 对其进行了测试,它在独立的 java 程序中运行良好。
加密
byte[] incrept = simpleCrypto.encrypt(KEY, simpleCrypto.getImageFile("E:/aeroplane.png"));
//Store encrypted file in SD card of your mobile with name vincent.mp3.
FileOutputStream fos = new FileOutputStream(new File("E:/out-aeroplane.png"));
fos.write(incrept);
fos.close();
解密
byte[] decrpt = simpleCrypto.decrypt(KEY, simpleCrypto.getImageFile("E:/out-aeroplane.png"));
//Store encrypted file in SD card of your mobile with name vincent.mp3.
FileOutputStream fosdecrypt = new FileOutputStream(new File("E:/outdecrypt-aeroplane.png"));
fosdecrypt.write(decrpt);
fosdecrypt.close();
加密解密逻辑
public byte[] getImageFile(String fileName) throws FileNotFoundException
{
byte[] Image_data = null;
byte[] inarry = null;
try {
File file = new File(fileName);
@SuppressWarnings("resource")
FileInputStream is = new FileInputStream (file); // use recorded file instead of getting file from assets folder.
int length = is.available();
Image_data = new byte[length];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
while ((bytesRead = is.read(Image_data)) != -1)
{
output.write(Image_data, 0, bytesRead);
}
inarry = output.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return inarry;
}
public byte[] encrypt(String seed, byte[] cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext);
// return toHex(result);
return result;
}
public byte[] decrypt(String seed, byte[] encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = encrypted;
byte[] result = decrypt(rawKey, enc);
return result;
}
//done
private byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
在将图像作为 InputStream 获取后的我的 apk 文件中,我在将它们转换为字节数组后对其进行解密。我再次将解密的字节数组转换为 BitmapFactory.decode 的输入流。我尝试了 decodeByteArray 和 decodeStream。两者都不起作用。
图像使用独立的 java 程序加密,并在 apk 中解密。(如果我在独立的 java 程序中解密,它工作正常。)
我收到错误消息 Failed to decode Stream javax.crypto.BadPaddingException: pad block损坏
public static Bitmap readBitmap(InputStream input) {
if (input == null)
return null;
try {
String KEY = "kumar";
byte[] inarry =IOUtils.toByteArray(input);
byte[] decrpt = SquarksCryptUtil.decrypt(KEY, inarry);
InputStream cleanStream = null;
cleanStream = new ByteArrayInputStream(decrpt);
// return BitmapFactory.decodeStream(cleanStream);
return BitmapFactory.decodeByteArray(decrpt, 0, decrpt.length);
// return BitmapFactory.decodeStream(input);
} catch (Exception e) {
Log.e(FILE_NAME, "Failed to decode Stream " + e);
return null;
} finally {
close(input);
}
}