[英]Securely Storing Keys in Android Keystore
我正在制作一个与服务器通信的android应用程序。 我在我的服务器上使用基于令牌的身份验证,并从服务器向客户端传递信息,我使用非对称加密。
这就是这个过程的方式
但是,我不知道如何将私钥安全地存储在密钥库中。 如果我在运行时存储它,密钥将在代码中输出,如果我在REST连接期间发送私钥,那么就没有加密的意义,因为黑客可以找到这两个密钥。 任何人都可以帮我创建最好的解决方案吗? THX提前!
您可以将私钥存储在共享首选项中,但使用生成的密钥加密,密钥将存储在Android KeyStore
,这将在存储私钥时提供更高的安全性。
请参阅下面Kotlin中的示例。 首先,您需要生成密钥:
fun generateSecretKey(): SecretKey {
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
val spec = KeyGenParameterSpec
.Builder(secretKeyAlias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
keyGenerator.init(spec)
return keyGenerator.generateKey()
}
它将自动存储在KeyStore
因为我们在获取KeyGenerator
实例时将其作为提供者提及。
之后,当您需要再次获取密钥时,您可以这样做:
fun getSecretKey(): SecretKey {
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
val secretKeyEntry = keyStore.getEntry(secretKeyAlias, null) as KeyStore.SecretKeyEntry
return secretKeyEntry.secretKey
}
或者你总是可以使用getSecretKey()
方法,如果从KeyStore
获得的是null
通过将最后一行更改为:
return secretKeyEntry.secretKey ?: generateSecretKey()
获得SecretKey
,您可以继续加密:
fun encrypt(data: String): ByteArray? {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
iv = cipher.iv
return cipher.doFinal(data.toByteArray())
}
这里,方法encrypt
将返回一个ByteArray
,您可以将其存储在SharedPreferences
。 注意:您还应该存储初始化向量(IV)。 它存储在iv
属性中。
要解密存储的数据,请使用以下方法:
fun decrypt(encrypted: ByteArray): String {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val spec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec)
val decoded = cipher.doFinal(encrypted)
return String(decoded, Charsets.UTF_8)
}
在这里,您必须将商店初始化向量(IV)传递给GCMParameterSpec
。
希望它会帮助某人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.