Skip to content

Commit

Permalink
Basierend auf einer möglichst geringen Änderung des Originalcodes wur…
Browse files Browse the repository at this point in the history
…den die folgenden zwei Punkte verbessert:

Optimieren Sie die Leistung und reduzieren Sie den durch unnötigen Code verursachten Leistungsaufwand.
Verbesserte Speichersicherheit, um zu verhindern, dass Ressourcen nicht sofort zurückgefordert werden.
  • Loading branch information
YangDai2003 committed Mar 25, 2024
1 parent d978461 commit ce5fa02
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,8 @@ class AESEncryptionHelper {
*/
@Throws(Exception::class)
fun readFile(file: File): ByteArray {
val fileContents = file.readBytes()
val inputBuffer = BufferedInputStream(FileInputStream(file))
inputBuffer.read(fileContents)
inputBuffer.close()
return fileContents
// read file to ByteArray
return file.readBytes()
}

/**
Expand All @@ -59,10 +56,12 @@ class AESEncryptionHelper {
*/
@Throws(Exception::class)
fun saveFile(fileData: ByteArray, file: File) {
val bos = BufferedOutputStream(FileOutputStream(file, false))
bos.write(fileData)
bos.flush()
bos.close()
// Even if an exception occurs in the use block, the resource will be closed correctly,
// which helps prevent resource leaks and improve application stability and performance.
BufferedOutputStream(FileOutputStream(file, false)).use { bos ->
bos.write(fileData)
bos.flush()
}
}

/**
Expand All @@ -84,15 +83,8 @@ class AESEncryptionHelper {
val charset = ('a'..'z') + ('A'..'Z') + ('1'..'9')
password = (1..stringLength).map { charset.random() }.joinToString("")

val secretKey = generateSecretKey(password, iv)
// the key can be saved plain, because i am using EncryptedSharedPreferences
val editor = sharedPref.edit()
editor.putString(BACKUP_SECRET_KEY, password)
// I use .commit because when using .apply the needed app restart is faster then apply
// and the preferences wont be saved
editor.commit()

return secretKey
// save key to shared pref
sharedPref.edit().putString(BACKUP_SECRET_KEY, password).commit()
}

// generate secretKey, and return it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class AESEncryptionManager {

private val aesEncryptionHelper = AESEncryptionHelper()

// Creating a new Cipher instance for each encryption and decryption operation may cause performance degradation because creating a Cipher instance is an expensive operation.
// Optimize this problem by creating a Cipher instance at the class level and reusing it when needed.
private val cipher = Cipher.getInstance("AES/GCM/NoPadding")

/**
* This method will encrypt the given data
* @param sharedPref : the sharedPref, to fetch the key
Expand Down Expand Up @@ -50,7 +54,6 @@ class AESEncryptionManager {
val secretKey = if (encryptPassword != null) { aesEncryptionHelper.getSecretKeyWithCustomPw(encryptPassword, iv)
} else aesEncryptionHelper.getSecretKey(sharedPref, iv)

val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val parameterSpec = GCMParameterSpec(128, iv)

//Encryption mode on!
Expand Down Expand Up @@ -84,24 +87,21 @@ class AESEncryptionManager {
)
fun decryptData(sharedPref: SharedPreferences, encryptPassword: String?, encryptedData: ByteArray): ByteArray {


//Wrap the data into a byte buffer to ease the reading process
val byteBuffer = ByteBuffer.wrap(encryptedData)
val noonceSize = byteBuffer.int
// There is no need to convert to ByteBuffer, which will cause additional performance overhead.
val noonceSize = encryptedData[0].toInt()

//Make sure that the file was encrypted properly
require(!(noonceSize < 12 || noonceSize >= 16)) { "Nonce size is incorrect. Make sure that the incoming data is an AES encrypted file." }
val iv = ByteArray(noonceSize)
byteBuffer[iv]

val iv = encryptedData.sliceArray(1 until noonceSize+1)

//Prepare your key/password
val secretKey = if (encryptPassword != null) { aesEncryptionHelper.getSecretKeyWithCustomPw(encryptPassword, iv)
} else aesEncryptionHelper.getSecretKey(sharedPref, iv)

//get the rest of encrypted data
val cipherBytes = ByteArray(byteBuffer.remaining())
byteBuffer[cipherBytes]
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val cipherBytes = encryptedData.sliceArray(noonceSize+1 until encryptedData.size)

val parameterSpec = GCMParameterSpec(128, iv)

//Encryption mode on!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,10 +386,10 @@ class RoomBackup(var context: Context) {
roomDatabase = null
if (backupIsEncrypted) {
val encryptedBytes = encryptBackup() ?: return
val bos = BufferedOutputStream(FileOutputStream(destination, false))
bos.write(encryptedBytes)
bos.flush()
bos.close()
BufferedOutputStream(FileOutputStream(destination, false)).use { bos ->
bos.write(encryptedBytes)
bos.flush()
}
} else {
// Copy current database to save location (/files dir)
copy(DATABASE_FILE, destination)
Expand Down Expand Up @@ -577,10 +577,10 @@ class RoomBackup(var context: Context) {
if (backupIsEncrypted) {
copy(source, TEMP_BACKUP_FILE)
val decryptedBytes = decryptBackup() ?: return
val bos = BufferedOutputStream(FileOutputStream(DATABASE_FILE, false))
bos.write(decryptedBytes)
bos.flush()
bos.close()
BufferedOutputStream(FileOutputStream(DATABASE_FILE, false)).use { bos ->
bos.write(decryptedBytes)
bos.flush()
}
} else {
if (fileExtension == "aes") {
if (enableLogDebug)
Expand Down Expand Up @@ -622,10 +622,10 @@ class RoomBackup(var context: Context) {
roomDatabase!!.close()
roomDatabase = null

val bos = BufferedOutputStream(FileOutputStream(DATABASE_FILE, false))
bos.write(decryptedBytes)
bos.flush()
bos.close()
BufferedOutputStream(FileOutputStream(DATABASE_FILE, false)).use { bos ->
bos.write(decryptedBytes)
bos.flush()
}
} else {
// Close the database
roomDatabase!!.close()
Expand Down

0 comments on commit ce5fa02

Please sign in to comment.