androidkotlinaesjncryptor

JNCryptor - RNCryptor Image file encryption / decryption


I am trying to get image encryption / decryption working using AES256 implementation of RNCryptor Library.

This is my code so far :

//Encrypt file
/**
 *
var encryptedData = RNCryptor.encrypt(data: data as Data, withPassword: hashKey.description)
try encryptedData.write(to: fileURL)
 * */
fun encryptFile( inputFile : File ) : File {

    val size = inputFile.length().toInt()
    val fileBytes = ByteArray(size)
    val aeS256JNCryptor = AES256JNCryptor()
    val file = File(Environment.getExternalStorageDirectory().toString() + "/Encrypted_" + inputFile.name)
    try {
        val buf = BufferedInputStream(FileInputStream(inputFile))
        buf.read(fileBytes, 0, fileBytes.size)

        val encryptedFileBytes = aeS256JNCryptor.encryptData(fileBytes, "master".toCharArray())

        val bufOut = BufferedOutputStream(FileOutputStream(file))
        bufOut.write(encryptedFileBytes)

        buf.close()
        bufOut.close()

    } catch (e: FileNotFoundException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    } catch (e: IOException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    }

    return file

}

//Decrypt file
/**
 *
let encryptedData = fileManager.contents(atPath: filePathNormal)
let decryptedData = try RNCryptor.decrypt(data: encryptedData!, withPassword: hashKey.description)
let selected_image = UIImage.sd_image(with: decryptedData)
 * */
fun decryptFile( inputFile : File ) : File {

    val size = inputFile.length().toInt()
    val fileBytes = ByteArray(size)
    val aeS256JNCryptor = AES256JNCryptor()
    val file = File(Environment.getExternalStorageDirectory().toString() + "/Decrypted_" + inputFile.name)
    try {
        val buf = BufferedInputStream(FileInputStream(inputFile))
        buf.read(fileBytes, 0, fileBytes.size)

        val decryptedFileBytes = aeS256JNCryptor.decryptData(fileBytes, "master".toCharArray())

        val bufOut = BufferedOutputStream(file.outputStream())
        bufOut.write(decryptedFileBytes)

        buf.close()
        bufOut.close()

    } catch (e: FileNotFoundException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    } catch (e: IOException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    }

    return file
}

Post decryption I am unable to load / view the image. I have posted relevant iOS code used in the comments. Please let me know if I am going wrong somewhere.

Here are somethings I've already tried with no success :

fun decryptFile( inputFile : File ) : File {

    val size = inputFile.length().toInt()
    val fileBytes = ByteArray(size)
    val aeS256JNCryptor = AES256JNCryptor()
    val file = File(Environment.getExternalStorageDirectory().toString() + "/Decrypted_" + inputFile.name)
    try {
        val buf = BufferedInputStream(FileInputStream(inputFile))
        buf.read(fileBytes, 0, fileBytes.size)

        val decryptedFileBytes = aeS256JNCryptor.decryptData(fileBytes, "master".toCharArray())

        if( file.exists() ) file.delete()

        //val bufOut = BufferedOutputStream(file.outputStream())
        //bufOut.write(decryptedFileBytes)

        val fileOutputStream = FileOutputStream( file.absolutePath )
        fileOutputStream.write(decryptedFileBytes)
        buf.close()
        fileOutputStream.close()
        //bufOut.close()

    } catch (e: FileNotFoundException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    } catch (e: IOException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    }

    return file
}

Alternate way to save bitmap :

val fileOutputStream = FileOutputStream( file.absolutePath )
        //fileOutputStream.write(decryptedFileBytes)

val bitmap = BitmapFactory.decodeByteArray(decryptedFileBytes, 0, decryptedFileBytes.size)
if( bitmap != null )
   bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)


buf.close()
fileOutputStream.close()

I am able to see the decrypted file, the size matches with that of original file, tried debugging byte array conversion to ensure bytes are the same as the original.

I am unable to open file either in Gallery / in app when loading it in an imageview.


Solution

  • It was solved by changing the way password is encrypted and used.

    Here's what worked :

    //Encrypt file
    /**
     *
    var encryptedData = RNCryptor.encrypt(data: data as Data, withPassword: hashKey.description)
    try encryptedData.write(to: fileURL)
     fileBytes - 3,1,-54,106
     encrypted - 3,1,71,68
     * */
    fun encryptFile( inputFile : File, privateKey : CharArray ) : File {
    
        val size = inputFile.length().toInt()
        val fileBytes = ByteArray(size)
        val aeS256JNCryptor = AES256JNCryptor()
        val file = File(Environment.getExternalStorageDirectory().toString() + "/Encrypted_" + inputFile.name)
        try {
            val buf = BufferedInputStream(FileInputStream(inputFile))
            buf.read(fileBytes, 0, fileBytes.size)
    
            val encryptedFileBytes = aeS256JNCryptor.encryptData(fileBytes, privateKey)
    
            val bufOut = BufferedOutputStream(FileOutputStream(file))
            bufOut.write(encryptedFileBytes)
    
            buf.close()
            bufOut.close()
    
        } catch (e: FileNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        } catch (e: IOException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        }
    
        return file
    
    }
    
    //Decrypt file
    /**
     *
    let encryptedData = fileManager.contents(atPath: filePathNormal)
    let decryptedData = try RNCryptor.decrypt(data: encryptedData!, withPassword: hashKey.description)
    let selected_image = UIImage.sd_image(with: decryptedData)
    encrypted - 3,1,71,68
    decrypted Bytes - 3,1,-54,106
     * */
    fun decryptFile( inputFile : File, privateKey: CharArray ) : File {
    
        val size = inputFile.length().toInt()
        val fileBytes = ByteArray(size)
        val aeS256JNCryptor = AES256JNCryptor()
        val file = File(Environment.getExternalStorageDirectory().toString() + "/Decrypted_" + inputFile.name)
        try {
            val buf = BufferedInputStream(FileInputStream(inputFile))
            buf.read(fileBytes, 0, fileBytes.size)
    
            val decryptedFileBytes = aeS256JNCryptor.decryptData(fileBytes, privateKey)
    
            if( file.exists() ) file.delete()
    
            val fileOutputStream = FileOutputStream( file.absolutePath )
            fileOutputStream.write(decryptedFileBytes)
    
            buf.close()
            fileOutputStream.close()
    
        } catch (e: FileNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        } catch (e: IOException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        }
    
        return file
    }
    

    privateKey is a random alphanumeric string of length 16. Once generated, it needs to be reused while encrypting and decrypting file.