diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt index 0e3a7a2c49..d5ff7a0f84 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt @@ -71,7 +71,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context, val encodedKey = Base64.encodeToString(key, Base64.NO_PADDING) val toStore = secretStoringUtils.securelyStoreString(encodedKey, alias) sharedPreferences.edit { - putString("${ENCRYPTED_KEY_PREFIX}_$alias", Base64.encodeToString(toStore!!, Base64.NO_PADDING)) + putString("${ENCRYPTED_KEY_PREFIX}_$alias", Base64.encodeToString(toStore, Base64.NO_PADDING)) } return key } @@ -84,7 +84,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context, val encryptedB64 = sharedPreferences.getString("${ENCRYPTED_KEY_PREFIX}_$alias", null) val encryptedKey = Base64.decode(encryptedB64, Base64.NO_PADDING) val b64 = secretStoringUtils.loadSecureSecret(encryptedKey, alias) - return Base64.decode(b64!!, Base64.NO_PADDING) + return Base64.decode(b64, Base64.NO_PADDING) } fun configureEncryption(realmConfigurationBuilder: RealmConfiguration.Builder, alias: String) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt index c3b2d7f161..c6c8cedf9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt @@ -58,23 +58,19 @@ import javax.security.auth.x500.X500Principal * is not available. * * Android [K-M[ - * For android >=KITKAT and =L and Older androids - * For older androids as a fallback we generate an AES key from the alias using PBKDF2 with random salt. - * The salt and iv are stored with encrypted data. - * * Sample usage: * * val secret = "The answer is 42" - * val KEncrypted = SecretStoringUtils.securelyStoreString(secret, "myAlias", context) + * val KEncrypted = SecretStoringUtils.securelyStoreString(secret, "myAlias") * //This can be stored anywhere e.g. encoded in b64 and stored in preference for example * * //to get back the secret, just call - * val kDecrypted = SecretStoringUtils.loadSecureSecret(KEncrypted!!, "myAlias", context) + * val kDecrypted = SecretStoringUtils.loadSecureSecret(KEncrypted, "myAlias") * * * You can also just use this utility to store a secret key, and use any encryption algorithm that you want. @@ -91,7 +87,6 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte private const val FORMAT_API_M: Byte = 0 private const val FORMAT_1: Byte = 1 - private const val FORMAT_2: Byte = 2 } private val keyStore: KeyStore by lazy { @@ -113,15 +108,14 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte /** * Encrypt the given secret using the android Keystore. * On android >= M, will directly use the keystore to generate a symmetric key - * On android >= KitKat and = Lollipop and = Build.VERSION_CODES.M -> encryptStringM(secret, keyAlias) else -> encryptString(secret, keyAlias) @@ -132,7 +126,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte * Decrypt a secret that was encrypted by #securelyStoreString() */ @Throws(Exception::class) - fun loadSecureSecret(encrypted: ByteArray, keyAlias: String): String? { + fun loadSecureSecret(encrypted: ByteArray, keyAlias: String): String { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> decryptStringM(encrypted, keyAlias) else -> decryptString(encrypted, keyAlias) @@ -180,7 +174,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte - Store the encrypted AES Generate a key pair for encryption */ - fun getOrGenerateKeyPairForAlias(alias: String): KeyStore.PrivateKeyEntry { + private fun getOrGenerateKeyPairForAlias(alias: String): KeyStore.PrivateKeyEntry { val privateKeyEntry = (keyStore.getEntry(alias, null) as? KeyStore.PrivateKeyEntry) if (privateKeyEntry != null) return privateKeyEntry @@ -205,7 +199,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte } @RequiresApi(Build.VERSION_CODES.M) - fun encryptStringM(text: String, keyAlias: String): ByteArray? { + private fun encryptStringM(text: String, keyAlias: String): ByteArray { val secretKey = getOrGenerateSymmetricKeyForAliasM(keyAlias) val cipher = Cipher.getInstance(AES_MODE) @@ -229,7 +223,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte return String(cipher.doFinal(encryptedText), Charsets.UTF_8) } - private fun encryptString(text: String, keyAlias: String): ByteArray? { + private fun encryptString(text: String, keyAlias: String): ByteArray { // we generate a random symmetric key val key = ByteArray(16) secureRandom.nextBytes(key) @@ -246,7 +240,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte return format1Make(encryptedKey, iv, encryptedBytes) } - private fun decryptString(data: ByteArray, keyAlias: String): String? { + private fun decryptString(data: ByteArray, keyAlias: String): String { val (encryptedKey, iv, encrypted) = format1Extract(ByteArrayInputStream(data)) // we need to decrypt the key @@ -307,22 +301,6 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte output.write(bos1.toByteArray()) } -// @RequiresApi(Build.VERSION_CODES.M) -// @Throws(IOException::class) -// fun saveSecureObjectM(keyAlias: String, file: File, writeObject: Any) { -// FileOutputStream(file).use { -// saveSecureObjectM(keyAlias, it, writeObject) -// } -// } -// -// @RequiresApi(Build.VERSION_CODES.M) -// @Throws(IOException::class) -// fun loadSecureObjectM(keyAlias: String, file: File): T? { -// FileInputStream(file).use { -// return loadSecureObjectM(keyAlias, it) -// } -// } - @RequiresApi(Build.VERSION_CODES.M) @Throws(IOException::class) private fun loadSecureObjectM(keyAlias: String, inputStream: InputStream): T? { @@ -443,32 +421,4 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte return bos.toByteArray() } - - private fun format2Make(salt: ByteArray, iv: ByteArray, encryptedBytes: ByteArray): ByteArray { - val bos = ByteArrayOutputStream(3 + salt.size + iv.size + encryptedBytes.size) - bos.write(FORMAT_2.toInt()) - bos.write(salt.size) - bos.write(salt) - bos.write(iv.size) - bos.write(iv) - bos.write(encryptedBytes) - - return bos.toByteArray() - } - - private fun format2Extract(bis: InputStream): Triple { - val format = bis.read() - assert(format.toByte() == FORMAT_2) - - val saltSize = bis.read() - val salt = ByteArray(saltSize) - bis.read(salt) - - val ivSize = bis.read() - val iv = ByteArray(ivSize) - bis.read(iv) - - val encrypted = bis.readBytes() - return Triple(salt, iv, encrypted) - } }