class CryptographyManagerImpl : CryptographyManager {
private val KEY_SIZE_BITS: Int = 256
private val GCM_TAG_BITS: Int = 128
private val ANDROID_KEYSTORE = "AndroidKeyStore"
private val KEY_NAME = "MySecretKey"
private val ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM
private val ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_NONE
private val ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES
@Throws(BiometricEncryptionException::class)
override fun getInitializedCypherForEncryption(): Cipher {
try {
val cipher = getCipher()
val secretKey = getOrCreateSecretKey(KEY_NAME)
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
return cipher
} catch (e: Exception) {
throw BiometricEncryptionException()
}
}
@Throws(BiometricEncryptionException::class)
@OptIn(ExperimentalEncodingApi::class)
override fun getInitializedCypherForDecryption(
encryptedData: String
): Cipher {
try {
val cipher = getCipher()
val secretKey = getOrCreateSecretKey(KEY_NAME)
val parts = encryptedData.split(":")
val iv = Base64.decode(parts[1], android.util.Base64.DEFAULT)
cipher.init(
Cipher.DECRYPT_MODE,
secretKey,
GCMParameterSpec(GCM_TAG_BITS, iv)
)
return cipher
} catch (e: Exception) {
throw BiometricEncryptionException()
}
}
@Throws(BiometricEncryptionException::class)
@OptIn(ExperimentalEncodingApi::class)
override fun encryptData(
data: String,
cipher: Cipher
): String {
try {
val byteArray = data.toByteArray(StandardCharsets.UTF_8)
val encryptedText = cipher.doFinal(byteArray)
val base64Text = Base64.encode(encryptedText, android.util.Base64.DEFAULT) + ":" + Base64.encode(cipher.iv, android.util.Base64.DEFAULT)
return base64Text
} catch (e: Exception) {
throw BiometricEncryptionException()
}
}
@Throws(BiometricEncryptionException::class)
@OptIn(ExperimentalEncodingApi::class)
override fun decryptData(
encryptedData: String,
cipher: Cipher
): String {
try {
val parts = encryptedData.split(":")
val encryptedText = Base64.decode(parts[0], android.util.Base64.DEFAULT)
val byteArray = cipher.doFinal(encryptedText)
val data = String(byteArray, StandardCharsets.UTF_8)
return data
} catch (e: Exception) {
throw BiometricEncryptionException()
}
}
private fun getCipher(): Cipher {
val transformation = "$ENCRYPTION_ALGORITHM/$ENCRYPTION_BLOCK_MODE/$ENCRYPTION_PADDING"
return Cipher.getInstance(transformation)
}
private fun getOrCreateSecretKey(keyName: String): SecretKey {
val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE).apply {
load(null)
}
keyStore.getKey(keyName, null)?.let {
return it as SecretKey
}
val paramsBuilder = KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).apply {
setBlockModes(ENCRYPTION_BLOCK_MODE)
setEncryptionPaddings(ENCRYPTION_PADDING)
setKeySize(KEY_SIZE_BITS)
setUserAuthenticationRequired(true)
setInvalidatedByBiometricEnrollment(true)
}
val keyGenParams = paramsBuilder.build()
val keyGenerator = KeyGenerator.getInstance(
ENCRYPTION_ALGORITHM,
ANDROID_KEYSTORE
)
keyGenerator.init(keyGenParams)
return keyGenerator.generateKey()
}
}
Der obige Code funktioniert einwandfrei auf Android 16. Unter Android 10 erhalte ich jedoch die im Titel dieser Frage gezeigte Ausnahme, wenn ich versuche, cipher.init für die Entschlüsselungschiffre aufzurufen.
Einige Dinge, die ich beobachtet habe:
Beim Aufruf von getInitializedCypherForEncryption , wenn ich das überprüfe cipher.iv unmittelbar nach cipher.init erhalte ich immer ein 12-Byte-Array;
Da ich BiometricPrompt und CryptoObject für zusätzliche Sicherheit verwende, hat sich der IV in ein 16-Byte-Array mit unterschiedlichen Werten geändert, wenn ich cipher.iv direkt nach der Erfassung des verifizierten Chiffrierobjekts noch einmal überprüfe;
Jetzt löst getInitializedCypherForDecryption die oben genannte Ausnahme direkt auf cipher.init aus, da sich die IV von selbst geändert hat;
Ich habe versucht, die ursprüngliche 12-Byte-IV zu behalten, um sie später wiederzuverwenden, aber die resultierenden Daten werden falsch entschlüsselt;
Ich habe auch versucht, das Original beizubehalten Cipher-Objekt, anstatt das verifizierte über CryptoObject weiterzuleiten, aber ich erhalte offensichtlich eine android.security.KeyStoreException: Key user not Authenticated;
Ich habe auch versucht, meine eigene 12-Byte-IV zu generieren, und habe die cipher.init von getInitializedCypherForEncryption eingefügt. Das gleiche Problem besteht weiterhin und außerdem wird der Code für Android 16 beschädigt, da das manuelle Setzen eines IV zu einer Ausnahme führt.
Ich versuche, die Datenverschlüsselung und -entschlüsselung mithilfe von Cipher zu implementieren. Das ist mein Code: [code]class CryptographyManagerImpl : CryptographyManager { private val KEY_SIZE_BITS: Int = 256 private val GCM_TAG_BITS: Int = 128 private val ANDROID_KEYSTORE = "AndroidKeyStore"
private val KEY_NAME = "MySecretKey" private val ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM private val ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_NONE private val ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES
@Throws(BiometricEncryptionException::class) override fun getInitializedCypherForEncryption(): Cipher { try { val cipher = getCipher() val secretKey = getOrCreateSecretKey(KEY_NAME) cipher.init(Cipher.ENCRYPT_MODE, secretKey) return cipher } catch (e: Exception) { throw BiometricEncryptionException() } }
@Throws(BiometricEncryptionException::class) @OptIn(ExperimentalEncodingApi::class) override fun getInitializedCypherForDecryption( encryptedData: String ): Cipher { try { val cipher = getCipher() val secretKey = getOrCreateSecretKey(KEY_NAME) val parts = encryptedData.split(":") val iv = Base64.decode(parts[1], android.util.Base64.DEFAULT) cipher.init( Cipher.DECRYPT_MODE, secretKey, GCMParameterSpec(GCM_TAG_BITS, iv) ) return cipher } catch (e: Exception) { throw BiometricEncryptionException() } }
@Throws(BiometricEncryptionException::class) @OptIn(ExperimentalEncodingApi::class) override fun decryptData( encryptedData: String, cipher: Cipher ): String { try { val parts = encryptedData.split(":") val encryptedText = Base64.decode(parts[0], android.util.Base64.DEFAULT) val byteArray = cipher.doFinal(encryptedText) val data = String(byteArray, StandardCharsets.UTF_8) return data } catch (e: Exception) { throw BiometricEncryptionException() } }
private fun getCipher(): Cipher { val transformation = "$ENCRYPTION_ALGORITHM/$ENCRYPTION_BLOCK_MODE/$ENCRYPTION_PADDING" return Cipher.getInstance(transformation) }
private fun getOrCreateSecretKey(keyName: String): SecretKey { val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE).apply { load(null) } keyStore.getKey(keyName, null)?.let { return it as SecretKey }
val paramsBuilder = KeyGenParameterSpec.Builder( keyName, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT ).apply { setBlockModes(ENCRYPTION_BLOCK_MODE) setEncryptionPaddings(ENCRYPTION_PADDING) setKeySize(KEY_SIZE_BITS) setUserAuthenticationRequired(true) setInvalidatedByBiometricEnrollment(true) }
val keyGenParams = paramsBuilder.build() val keyGenerator = KeyGenerator.getInstance( ENCRYPTION_ALGORITHM, ANDROID_KEYSTORE ) keyGenerator.init(keyGenParams) return keyGenerator.generateKey() } } [/code] Der obige Code funktioniert einwandfrei auf Android 16. Unter Android 10 erhalte ich jedoch die im Titel dieser Frage gezeigte Ausnahme, wenn ich versuche, cipher.init für die Entschlüsselungschiffre aufzurufen. Einige Dinge, die ich beobachtet habe: [list] [*]Beim Aufruf von getInitializedCypherForEncryption , wenn ich das überprüfe cipher.iv unmittelbar nach cipher.init erhalte ich immer ein 12-Byte-Array;
[*]Da ich BiometricPrompt und CryptoObject für zusätzliche Sicherheit verwende, hat sich der IV in ein 16-Byte-Array mit unterschiedlichen Werten geändert, wenn ich cipher.iv direkt nach der Erfassung des verifizierten Chiffrierobjekts noch einmal überprüfe;
[*]Jetzt löst getInitializedCypherForDecryption die oben genannte Ausnahme direkt auf cipher.init aus, da sich die IV von selbst geändert hat;
[*]Ich habe versucht, die ursprüngliche 12-Byte-IV zu behalten, um sie später wiederzuverwenden, aber die resultierenden Daten werden falsch entschlüsselt;
[*]Ich habe auch versucht, das Original beizubehalten Cipher-Objekt, anstatt das verifizierte über CryptoObject weiterzuleiten, aber ich erhalte offensichtlich eine android.security.KeyStoreException: Key user not Authenticated;
[*]Ich habe auch versucht, meine eigene 12-Byte-IV zu generieren, und habe die cipher.init von getInitializedCypherForEncryption eingefügt. Das gleiche [url=viewtopic.php?t=26065]Problem[/url] besteht weiterhin und außerdem wird der Code für Android 16 beschädigt, da das manuelle Setzen eines IV zu einer Ausnahme führt.
[/list] Habe ich etwas übersehen? Vielen Dank im Voraus.
Bildbeschreibung eingeben, das hier eine Python -Funktion schreibe, um IPv4 Adressen zu validieren. für eine Aufgabe von CS50 Python. Meine Funktion sollte:
sicherstellen, dass das Format x.x.x.x...
Ich habe eine Flash -Datei (binär), die Teil von Firmware ist. Ich möchte es mit dem Programmierer auf 2Gib Nand Flash programmieren und muss alle 2048 Bytes Flash -Datei (wie OOB) 64 Bytes...
Ich habe eine Flash -Datei (binär), die Teil von Firmware ist. Ich möchte es mit dem Programmierer auf 2Gib Nand Flash programmieren und muss alle 2048 Bytes Flash -Datei (wie OOB) 64 Bytes...
Diese Frage wurde mit tatsächlich funktionierendem Code aktualisiert.
(Hinweis: In dieser Diskussion geht es um die Art und Weise, wie das Array-Interop funktioniert, was relevant sein könnte.)
Ich...
Ich habe ein Problem mit dem Befehl LoadData meiner Django -App. é Das befindet sich in meiner Datenbanktabelle. oder unterschiedliche Charaktertyp oder Collation -Inaleinstellungen wie C oder...