我的问题是这样的:我试图先加密一些用户的敏感数据,然后再将其保存到数据库中。加密不是问题,问题始于解密部分。
我明白了:
07-22 16:25:38.941 18035-18035/io.nourish.strongerasfukk E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.nourish.strongerasfukk, PID: 18035
java.lang.RuntimeException: Unable to start activity ComponentInfo{io.nourish.strongerasfukk/io.nourish.strongerasfukk.Register}: java.security.InvalidKeyException: Keystore operation failed
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.security.InvalidKeyException: Keystore operation failed
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:692)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712)
at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612)
at javax.crypto.Cipher.tryCombinations(Cipher.java:532)
at javax.crypto.Cipher.getSpi(Cipher.java:437)
at javax.crypto.Cipher.init(Cipher.java:815)
at javax.crypto.Cipher.init(Cipher.java:774)
at **io.nourish.strongerasfukk.utilities.Encryption.decrypt(Encryption.kt:28)
at io.nourish.strongerasfukk.Register.onCreate(Register.kt:54)**
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.security.KeyStoreException: Incompatible padding mode
at android.security.KeyStore.getKeyStoreException(KeyStore.java:632)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712)
at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612)
at javax.crypto.Cipher.tryCombinations(Cipher.java:532)
at javax.crypto.Cipher.getSpi(Cipher.java:437)
at javax.crypto.Cipher.init(Cipher.java:815)
at javax.crypto.Cipher.init(Cipher.java:774)
at io.nourish.strongerasfukk.utilities.Encryption.decrypt(Encryption.kt:28)
at io.nourish.strongerasfukk.Register.onCreate(Register.kt:54)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
如您所见,问题引用了以下两行代码:
Encryption.kt(第28行)
cipher.init(Cipher.DECRYPT_MODE, key)
&
Register.kt(第54行)
var decryptedData = encryption.decrypt(encryptedData,masterKey?.private)
我试图将Cipher.init放在提供程序中,也可能没有提供程序,但出现了相同的错误;我在网上或在这里寻求一些解决方案,但一无所获。我在想什么或做错了什么?另外,我在这里(Link)尝试了该示例,但也没有任何结果。
我从此链接(link中获得了代码示例,但不得不将某些内容修改为自己的用途。
为了更好的理解,这是我的代码。
KeyStoreAdapter.kt
class KeyStoreAdapter {
private val kS = createAndroidKeyStore()
fun checkIfKeyExists(key: String) {
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
val alias = keyStore.aliases().toList()
if(!alias.contains(key)) {
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder("MasterKeys", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build()
kpg.initialize(parameterSpec)
kpg.generateKeyPair()
}
}
fun getKeys(alias: String): KeyPair? {
val privateKey = kS.getKey(alias, null) as PrivateKey?
val publicKey = kS.getCertificate(alias)?.publicKey
return if(privateKey != null && publicKey != null) {
KeyPair(publicKey, privateKey)
} else {
null
}
}
private fun createAndroidKeyStore(): KeyStore {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
return keyStore
}
}
Encryption.kt 类加密{
val cipher = Cipher.getInstance(Config.TRANSFORMATION)
fun encrypt(data: String, key: Key?): String {
cipher.init(Cipher.ENCRYPT_MODE, key)
val bytes = cipher.doFinal(data.toByteArray())
return Base64.encodeToString(bytes, Base64.DEFAULT)
}
fun decrypt(data: String, key: Key?): String {
cipher.init(Cipher.DECRYPT_MODE, key)
val encryptedData = Base64.decode(data, Base64.DEFAULT)
val decodedData = cipher.doFinal(encryptedData)
return String(decodedData)
}
}
const val TRANSFORMATION = "RSA/ECB/PKCS1Padding"
提前感谢大家!
答案 0 :(得分:1)
尝试将填充用作“ OAEPwithSHA-1和MGF1Padding”。 SDK 10+支持该功能。 代码:
const val TRANSFORMATION = "RSA/ECB/OAEPwithSHA-1andMGF1Padding"
生成密钥
val keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
keyPairGenerator.initialize(KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_ENCRYPT
or KeyProperties.PURPOSE_DECRYPT)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.setDigests(KeyProperties.DIGEST_SHA1)
.build())