android - 如何解决谷歌安全警报 - 不太安全的加密模式
问题描述
下面是我的代码,它的加密不太安全,来自 google playstore 的警报。指向 encrypter.kt 文件中的加密方法。任何人都可以帮助摆脱这个警报。我对加密技术的了解很少。
**Encryptor.kt**
内部类加密器{
private var iv: ByteArray? = null
@Throws(UnrecoverableEntryException::class, NoSuchAlgorithmException::class, KeyStoreException::class, NoSuchProviderException::class, NoSuchPaddingException::class, InvalidKeyException::class, IOException::class, InvalidAlgorithmParameterException::class, SignatureException::class, BadPaddingException::class, IllegalBlockSizeException::class)
fun encryptText(alias: String, textToEncrypt: String): ByteArray? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(alias))
iv = cipher.iv
return cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8))
}
else{
return encrypt(alias,textToEncrypt)
}
}
@Throws(NoSuchAlgorithmException::class, NoSuchProviderException::class, InvalidAlgorithmParameterException::class)
private fun getSecretKey(alias: String): SecretKey {
val keyGenerator: KeyGenerator
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE)
keyGenerator.init(KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build())
} else {
// or something like
keyGenerator = KeyGenerator.getInstance("AES", ANDROID_KEY_STORE)
// use the supported init method here such as this one: https://developer.android.com/reference/javax/crypto/KeyGenerator.html#init(int, java.security.SecureRandom)
keyGenerator.init(256)
}
return keyGenerator.generateKey()
}
fun getIv():ByteArray? {
return iv
}
@Throws(Exception::class)
fun encrypt(seed: String, cleartext: String): ByteArray {
iv = getivNew(seed.toByteArray())
return encrypt(iv!!, cleartext.toByteArray())
}
@Throws(Exception::class)
private fun encrypt(raw: ByteArray, clear: ByteArray): ByteArray {
val skeySpec = SecretKeySpec(raw, "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
val encrypted = cipher.doFinal(clear)
return encrypted
}
@Throws(Exception::class)
private fun getivNew(seed: ByteArray): ByteArray {
val md = MessageDigest.getInstance("MD5")
val md5Bytes = md.digest(seed) // 128 Bit = 16 byte SecretKey
val skey = SecretKeySpec(md5Bytes, "AES")
return skey.getEncoded()
}
companion object {
private const val TRANSFORMATION = "AES/GCM/NoPadding"
private const val ANDROID_KEY_STORE = "AndroidKeyStore"
}
}
解密器.kt
内部类 Decryptor @Throws(CertificateException::class, NoSuchAlgorithmException::class, KeyStoreException::class, IOException::class)
构造函数(){
private var keyStore: KeyStore? = null
init {
initKeyStore()
}
@Throws(KeyStoreException::class, CertificateException::class, NoSuchAlgorithmException::class, IOException::class)
private fun initKeyStore() {
keyStore = KeyStore.getInstance(ANDROID_KEY_STORE)
keyStore?.load(null)
}
@Throws(UnrecoverableEntryException::class, NoSuchAlgorithmException::class, KeyStoreException::class, NoSuchProviderException::class, NoSuchPaddingException::class, InvalidKeyException::class, IOException::class, BadPaddingException::class, IllegalBlockSizeException::class, InvalidAlgorithmParameterException::class)
fun decryptData(alias: String, encryptedData: ByteArray, encryptionIv: ByteArray): String {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val cipher = Cipher.getInstance(TRANSFORMATION)
val spec = GCMParameterSpec(128, encryptionIv)
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(alias), spec)
return String(cipher.doFinal(encryptedData), Charsets.UTF_8)
}
else{
return decrypt(encryptionIv,encryptedData)
}
}
@Throws(NoSuchAlgorithmException::class, UnrecoverableEntryException::class, KeyStoreException::class)
private fun getSecretKey(alias: String): SecretKey {
return (keyStore?.getEntry(alias, null) as KeyStore.SecretKeyEntry).secretKey
}
@Throws(Exception::class)
private fun decrypt(raw: ByteArray, encrypted: ByteArray): String {
val skeySpec = SecretKeySpec(raw, "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
val decrypted = cipher.doFinal(encrypted)
return String(decrypted)
}
companion object {
private const val TRANSFORMATION = "AES/GCM/NoPadding"
private const val ANDROID_KEY_STORE = "AndroidKeyStore"
}
}
SimpleCrypto.kt
对象 SimpleCrypto {
private val HEX = "0123456789ABCDEF"
@Throws(Exception::class)
fun decryptNew(seed: String, encrypted: String): String {
val rawKey = getRawKeyNew(seed.toByteArray())
val enc = toByte(encrypted)
val result = decrypt(rawKey, enc)
return String(result)
}
@Throws(Exception::class)
private fun getRawKeyNew(seed: ByteArray): ByteArray {
val md = MessageDigest.getInstance("MD5")
val md5Bytes = md.digest(seed) // 128 Bit = 16 byte SecretKey
val skey = SecretKeySpec(md5Bytes, "AES")
return skey.getEncoded()
}
@Throws(Exception::class)
private fun decrypt(raw: ByteArray, encrypted: ByteArray): ByteArray {
val skeySpec = SecretKeySpec(raw, "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
return cipher.doFinal(encrypted)
}
fun toByte(hexString: String): ByteArray {
val len = hexString.length / 2
val result = ByteArray(len)
for (i in 0 until len)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
16).toByte()
return result
}
}
解决方案
推荐阅读
- json - 在 React Native 中为图像创建 JSON 文件夹
- sql - ORA-00936: 缺少表达式,仅在日期时间列上按日期分组
- javascript - ReactJS:映射数据未显示在视图中
- php - 如何解决生产 Laravel 中禁止的数据表 403?
- powershell - 将for循环的变量插入另一个变量名
- php - 如何计算最佳数字以用于 php 中的百分比问题
- java - 如何从数组内部的字符串创建回文
- java - curveVertex()不在处理中绘制?
- javascript - 如何将带参数的函数作为javascript中的参数传递给函数?
- go - 写入 TOML 文件时发现重复键;tree.Has() 没有按预期工作