Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load Cipher encrypted image file in ImageView without saving to device

I am creating an application with content security for no one could ever copy the contents and files. I am using cipher to encrypt the image directly from the URL, with out downloading to the device. Please find my code below.

URL url = new URL(images.getImageurl());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
File folder = new File(Environment.getExternalStorageDirectory(), "zerb");
boolean success = true;

if (!folder.exists()){
folder.mkdirs();
}
InputStream fis = connection.getInputStream();
String path = folder.getAbsolutePath() + "images.getImageName + ".jpg";
encryptfile(fis, path, AppConstants.password + images.getContentid() + images.getTopicid())
fis.close();

And the cipher encryption Method code is

private static boolean encryptfile(InputStream inputStream, String path, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {

    FileOutputStream fos = new FileOutputStream(path.concat(".crypt"));
    byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16);
    SecretKeySpec sks = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    int b;
    byte[] d = new byte[8];
    while ((b = inputStream.read(d)) != -1) {
        cos.write(d, 0, b);
    }
    cos.flush();
    cos.close();
    inputStream.close();
    File encryptedFile = new File(path.concat(".crypt"));
    return (encryptedFile.exists());
}

and the decryption code is

 public static void decrypt(String path, String password, String outPath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream(path);
    FileOutputStream fos = new FileOutputStream(outPath);
    byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16);
    SecretKeySpec sks = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    int b;
    byte[] d = new byte[8];
    while ((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }
    fos.flush();
    fos.close();
    cis.close();
}

If I decrypt the image, it will be shown and can be copied from the device. All I need is to load the encrypted image to an ImageView without saving the decrypted image to the device, so that no one can copy. Please someone help me.

like image 957
Cecil Paul Avatar asked Jun 26 '18 12:06

Cecil Paul


People also ask

How do I encrypt a photo file?

Right-click (or press and hold) a file or folder and select Properties. Select the Advanced button and select the Encrypt contents to secure data check box. Select OK to close the Advanced Attributes window, select Apply, and then select OK.


1 Answers

An ImageView can show an in-memory android.graphics.Bitmap which can be read in directly from an InputStream.

For example, the decrypt() method could be adapted to return a Bitmap :

public Bitmap decrypt(String path, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream(path);
    byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16);
    SecretKeySpec sks = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);

    Bitmap bitmap = BitmapFactory.decodeStream(cis);
    cis.close();

    return bitmap;
}

(Although it's called Bitmap, it's fine to decode a .jpg or .png).

Then this can be shown in the ImageView:

ImageView imageView = findViewById(R.id.imageView);
Bitmap bitmap = decrypt(path + ".crypt", password);
imageView.setImageBitmap(bitmap);
like image 50
df778899 Avatar answered Sep 19 '22 07:09

df778899