fix(android): file encryption

This commit is contained in:
Hugo Pointcheval 2023-04-05 15:16:45 +02:00
parent 108c394a25
commit 0bf72447a0
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
3 changed files with 46 additions and 42 deletions

View File

@ -111,7 +111,7 @@ class NativeCrypto(private val context: Context) : NativeCryptoAPI {
): Boolean { ): Boolean {
// For now, only AES is supported // For now, only AES is supported
val aes = AES() val aes = AES()
val params = FileParameters(context, plainTextPath, cipherTextPath) val params = FileParameters(context, cipherTextPath, plainTextPath)
return aes.decryptFile(params, key) return aes.decryptFile(params, key)
} }

View File

@ -2,6 +2,9 @@ package fr.pointcheval.native_crypto_android.ciphers
import fr.pointcheval.native_crypto_android.interfaces.Cipher import fr.pointcheval.native_crypto_android.interfaces.Cipher
import fr.pointcheval.native_crypto_android.utils.FileParameters import fr.pointcheval.native_crypto_android.utils.FileParameters
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream import javax.crypto.CipherOutputStream
import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
@ -60,28 +63,32 @@ class AES : Cipher {
cipherInstance!!.init(javax.crypto.Cipher.ENCRYPT_MODE, sk) cipherInstance!!.init(javax.crypto.Cipher.ENCRYPT_MODE, sk)
} }
var len: Int? val input = BufferedInputStream(fileParameters.getFileInputStream())
val buffer = ByteArray(8192)
val inputFile = fileParameters.getFileInputStream()
val outputFile = fileParameters.getFileOutputStream()
val iv: ByteArray? = cipherInstance!!.iv
outputFile?.write(iv) var outputBuffered = BufferedOutputStream(fileParameters.getFileOutputStream(false))
outputFile?.flush() val iv: ByteArray = cipherInstance!!.iv
// Prepend the IV to the cipherText file
outputBuffered.write(iv)
outputBuffered.flush()
outputBuffered.close()
// Reopen the file and append the cipherText
outputBuffered = BufferedOutputStream(fileParameters.getFileOutputStream(true))
val output = CipherOutputStream(outputBuffered, cipherInstance)
var i: Int
do {
i = input.read()
if (i != -1) output.write(i)
} while (i != -1)
output.flush()
output.close()
input.close()
outputBuffered.close()
val encryptedStream = CipherOutputStream(outputFile!!, cipherInstance)
while(true) {
len = inputFile?.read(buffer)
if (len != null && len > 0) {
encryptedStream.write(buffer,0,len)
} else {
break
}
}
encryptedStream.flush()
encryptedStream.close()
inputFile?.close()
outputFile.close()
return fileParameters.outputExists() return fileParameters.outputExists()
} }
@ -110,9 +117,7 @@ class AES : Cipher {
val inputFile = fileParameters.getFileInputStream() ?: throw Exception("Error while reading IV") val inputFile = fileParameters.getFileInputStream() ?: throw Exception("Error while reading IV")
// Read the first 12 bytes from the file // Read the first 12 bytes from the file
for (i in 0 until 12) { inputFile.read(iv)
iv[i] = inputFile.read().toByte()
}
// Initialize secret key spec // Initialize secret key spec
val sk = SecretKeySpec(key, "AES") val sk = SecretKeySpec(key, "AES")
@ -125,21 +130,19 @@ class AES : Cipher {
cipherInstance!!.init(javax.crypto.Cipher.DECRYPT_MODE, sk, gcmParameterSpec) cipherInstance!!.init(javax.crypto.Cipher.DECRYPT_MODE, sk, gcmParameterSpec)
var len: Int? val input = CipherInputStream(BufferedInputStream(inputFile), cipherInstance)
val buffer = ByteArray(8192) val output = BufferedOutputStream(fileParameters.getFileOutputStream(false))
val outputFile = fileParameters.getFileOutputStream()
val decryptedStream = CipherOutputStream(outputFile!!, cipherInstance) var i: Int
while (true) { do {
len = inputFile.read(buffer) i = input.read()
if(len > 0){ if (i != -1) output.write(i)
decryptedStream.write(buffer,0, len) } while (i != -1)
} else {
break output.flush()
} output.close()
}
decryptedStream.flush() input.close()
decryptedStream.close()
inputFile.close()
return fileParameters.outputExists() return fileParameters.outputExists()
} }

View File

@ -43,14 +43,15 @@ class FileParameters(ctx: Context, input: String, output: String) {
} }
} }
fun getFileOutputStream(): OutputStream? { fun getFileOutputStream(append: Boolean): OutputStream? {
val path = outputPath val path = outputPath
return try{ return try{
FileOutputStream(path) FileOutputStream(path, append)
} catch(e: IOException){ } catch(e: IOException){
val documentFile: DocumentFile = this.getDocumentFileByPath(path) val documentFile: DocumentFile = this.getDocumentFileByPath(path)
val documentUri = documentFile.uri val documentUri = documentFile.uri
context.contentResolver.openOutputStream(documentUri) val mode = if(append) "wa" else "w"
context.contentResolver.openOutputStream(documentUri, mode)
} }
} }