- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
背景
在我使用的一个应用程序中,我将重要的东西( token )存储到 EncryptedSharedPreferences 中(取自 here 和 here ):
/** a hardware-encrypted based shared preference (for the values).
* Note that it is a bit slow, so it's better to always use it in a background thread.
* Also, avoid having it being backed-up in the manifest, as it's hardware based and will become useless: https://stackoverflow.com/a/63795282/878126*/
object SecuredSharedPreferences {
private var cachedDefaultSharedPreferences: SharedPreferences? = null
/**warning: using this function can take some time (249 ms on Pixel 4, for example). Very recommended to avoid calling it on UI thread */
@WorkerThread
fun getDefaultSecuredSharedPreferences(context: Context): SharedPreferences {
if (cachedDefaultSharedPreferences != null)
return cachedDefaultSharedPreferences!!
synchronized(this) {
if (cachedDefaultSharedPreferences != null)
return cachedDefaultSharedPreferences!!
cachedDefaultSharedPreferences = getSecuredSharedPreferences(context, context.packageName + "_secured_preferences")
}
return cachedDefaultSharedPreferences!!
}
@WorkerThread
private fun getSecuredSharedPreferences(context: Context, fileName: String): SharedPreferences {
val masterKey = MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()
return EncryptedSharedPreferences.create(context, fileName, masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
}
毕业典礼:
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
问题
MasterKey.Builder
GeneralSecurityException
行: Fatal Exception: java.security.GeneralSecurityException: Keystore operation failed
at androidx.security.crypto.MasterKeys.generateKey(MasterKeys.java:146)
at androidx.security.crypto.MasterKeys.getOrCreate(MasterKeys.java:97)
at androidx.security.crypto.MasterKey$Builder.buildOnM(MasterKey.java:357)
at androidx.security.crypto.MasterKey$Builder.build(MasterKey.java:314)
...
Caused by java.security.ProviderException: Keystore operation failed
at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi.engineGenerateKey(AndroidKeyStoreKeyGeneratorSpi.java:372)
at javax.crypto.KeyGenerator.generateKey(KeyGenerator.java:612)
at androidx.security.crypto.MasterKeys.generateKey(MasterKeys.java:142)
at androidx.security.crypto.MasterKeys.getOrCreate(MasterKeys.java:97)
at androidx.security.crypto.MasterKey$Builder.buildOnM(MasterKey.java:357)
at androidx.security.crypto.MasterKey$Builder.build(MasterKey.java:314)
EncryptedSharedPreferences.create
KeyStoreException
行,并且更频繁地出现并为更多用户提供:Fatal Exception: java.security.KeyStoreException: the master key android-keystore://_androidx_security_master_key_ exists but is unusable
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:275)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:236)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
...
Caused by java.security.UnrecoverableKeyException: Failed to obtain information about key
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:282)
at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:98)
at java.security.KeyStore.getKey(KeyStore.java:825)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.<init>(AndroidKeystoreAesGcm.java:58)
at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.getAead(AndroidKeystoreKmsClient.java:164)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:267)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:236)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
编辑:似乎还有更多类型的异常(exception):
Fatal Exception: com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1566)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1663)
at com.google.crypto.tink.proto.Keyset.parseFrom(Keyset.java:957)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read(SharedPrefKeysetReader.java:84)
at com.google.crypto.tink.CleartextKeysetHandle.read(CleartextKeysetHandle.java:58)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:328)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:160)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
Fatal Exception: java.lang.NullPointerException: Attempt to invoke interface method 'android.security.keymaster.OperationResult android.security.IKeystoreService.begin(android.os.IBinder, java.lang.String, int, boolean, android.security.keymaster.KeymasterArguments, byte[], int)' on a null object reference
at android.security.KeyStore.begin(KeyStore.java:501)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:248)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:109)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2977)
at javax.crypto.Cipher.tryCombinations(Cipher.java:2884)
at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2789)
at javax.crypto.Cipher.chooseProvider(Cipher.java:956)
at javax.crypto.Cipher.init(Cipher.java:1199)
at javax.crypto.Cipher.init(Cipher.java:1143)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encryptInternal(AndroidKeystoreAesGcm.java:84)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encrypt(AndroidKeystoreAesGcm.java:72)
at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.validateAead(AndroidKeystoreKmsClient.java:248)
at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.getAead(AndroidKeystoreKmsClient.java:165)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:267)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:236)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
我试过的
wrap the initialization of EncryptedSharedPreferences with "clear all data if fails" and bite the bullet
.还建议它可能与拥有
android:allowBackup
有关。被禁用(确实如此)。
android:allowBackup
相关?被禁用?
最佳答案
在使用 Jetpack Security EncryptedSharedPreferences(甚至是稳定的)之前要小心这个 Activity 故障,它主要来自外来设备 - https://issuetracker.google.com/issues/176215143?pli=1
唯一肮脏的解决方法是 - https://github.com/google/tink/issues/535#issuecomment-912661574
一旦找到友好的解决方案,我将更新答案。这是解决方法 -
/**
* A builder for creating an encrypted shared preference class.
*/
private const val KEYSTORE_PROVIDER = "AndroidKeyStore"
private const val SHARED_PREFS_FILENAME = "TVPrefs"
@KoinApiExtension
class EncryptedSharedPreferenceBuilder(var context: Context) : KoinComponent {
private val reporter: Reporter by inject()
private val masterKeyAlias =
MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()
fun build(): SharedPreferences {
return try {
createSharedPreferences()
} catch (gsException: GeneralSecurityException) {
reporter.logException(gsException)
Timber.d("EncryptedSharedPref: Error occurred while create shared pref=$gsException")
// There's not much point in keeping data you can't decrypt anymore,
// delete & re-create; user has to start from scratch
deleteSharedPreferences()
createSharedPreferences()
}
}
private fun createSharedPreferences() = EncryptedSharedPreferences.create(
context,
SHARED_PREFS_FILENAME,
masterKeyAlias,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
// Clearing getSharedPreferences using default Preference wrapper.
// This is to work around any key-mismatches that may happen.
fun clearSharedPreference() {
context.getSharedPreferences(SHARED_PREFS_FILENAME, Context.MODE_PRIVATE).edit().clear()
.apply()
}
// Workaround [https://github.com/google/tink/issues/535#issuecomment-912170221]
// Issue Tracker - https://issuetracker.google.com/issues/176215143?pli=1
private fun deleteSharedPreferences() {
try {
val sharedPrefsFile =
File("${context.filesDir.parent}/shared_prefs/$SHARED_PREFS_FILENAME.xml")
// Clear the encrypted prefs
clearSharedPreference()
// Delete the encrypted prefs file
if (sharedPrefsFile.exists()) {
val deleted = sharedPrefsFile.delete()
Timber.d("EncryptedSharedPref: Shared pref file deleted=$deleted; path=${sharedPrefsFile.absolutePath}")
} else {
Timber.d("EncryptedSharedPref: Shared pref file non-existent; path=${sharedPrefsFile.absolutePath}")
}
// Delete the master key
val keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER)
keyStore.load(null)
keyStore.deleteEntry(MasterKey.DEFAULT_MASTER_KEY_ALIAS)
} catch (e: Exception) {
Timber.d("EncryptedSharedPref: Error occurred while trying to reset shared pref=$e")
}
}
}
关于android - 使用 EncryptedSharedPreferences 获取 KeyStoreException 和 GeneralSecurityException,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65463893/
使用下一个描述获取崩溃: Caused by java.security.UnrecoverableKeyException: Failed to obtainX.509 form of public
我正在尝试在用户通过 Android M Fingerprint API 进行身份验证后解密加密文本。我一直在尝试关注 Android Security samples ,以及 KeyGenParam
我有一个 Android 应用程序,它使用 Android 安全 keystore 来加密/解密帐户信息。 最小 SDK 设置为 23,因此有效的 keystore 应该始终可用,但是,我收到了少量关
我无法在 Android 上解密之前加密的字符串。问题主要出现在运行 Android 6 Marshmallow 的索尼设备(Xperia Z5 和 Xperia Z5 Compact)上。 andr
我的目标是从 CAC 卡中读取信息并使用 pkcs11 从中提取信息并签署我的文档。我找不到适合我的硬件的 dll,因此我在我的计算机上安装了 openSC 并在以下代码中使用了 opensc-pkc
我们已经生成了 AndroidKeystore,它工作正常但随机遇到以下问题。 App重新安装后运行正常。 java.security.KeyStoreException: Failed to sto
我试图通过模拟 KeyStore 和 KeyStore.getInstance(KEYSTORE_TYPE) 来覆盖 KeyStoreException block 。但是当我模拟 KeyStore
如何在java sun keytool中创建.bks keystore ,我应该做什么? C:\Program Files\Java\jdk1.6.0\jre\bin>keytool -genkey
我尝试生成一个 RSA CA key 对和证书并将其保存到 keystore 。我的代码是: import java.io.FileOutputStream; import java.math.Big
我无法从 Android 上的 KeyStore 获取(私有(private)) key 。问题主要出现在三星设备(S6、S6 Edge)和 Android 6 上。 android.security
当我尝试在我的 Android 应用程序中对从外部获取的散列值进行签名时,出现上述异常。 生成 key 对的代码是: public static KeyPair generateKeyPair(Con
我将我的 spring boot 项目连接到 mysql 和 cassandra 数据库。当我使用 spring boot 在本地运行它时,一切正常。我使用 docker-compose 来运行这三个
在我们的应用中,我们遇到了 Android keystore 中的数据突然变得无法访问的问题。我们看到的具体异常如下: java.security.UnrecoverableKeyException:
我将我的 spring boot 项目连接到 mysql 和 cassandra 数据库。当我使用 spring boot 在本地运行它时,一切正常。我使用 docker-compose 来运行这三个
背景 在我使用的一个应用程序中,我将重要的东西( token )存储到 EncryptedSharedPreferences 中(取自 here 和 here ): /** a hardware-en
当我尝试创建 JKS 文件,将其写入磁盘,然后运行 keytool 将其转换为 P12 时,出现此错误。我走这条路的原因是因为我无法在代码中获得适用于 iOS 的 P12(不是加密人士)。那里有足
您好,我是 SSL 握手的新手。我已经从浏览器下载了服务器证书并尝试使用 keytool 创建一个 keystore 。我将证书存储为 .cer with der encoding 。但我正在关注 k
我的应用使用 Android 6.0 Fingerprint API 来保护 Android KeyStore 中的 AES key 。存储的 key 只能在用户通过指纹传感器验证时使用,因为 Key
所以我编写了我的应用程序,其中我使用 KeyStore 来加密/解密数据。我还为它编写了一个很好的 Robolectric 测试,但是当我尝试运行测试时,出现以下异常: java.security.K
我遇到 android.security.KeyStoreException: Unknown error 在极少数具有不同 Android 版本 (6 - 8) 的设备上 这是我的 key 生成代码
我是一名优秀的程序员,十分优秀!