我决定使用来自 AndroidX 安全库的新 EncryptedSharedPreferences。由于该应用程序支持 API 21 及更高版本,我决定试用这个新的 v1.1.0-alpha02 版本,因为它支持 API 21+
因此,我成功实现了 API 23+,但对于不支持 Android KeyStore 的旧版本,我无法正确实现,并且没有确切的说明应该如何创建主密钥以使其以某种方式工作.
初始化 SharedPrefs 的代码:
EncryptedSharedPreferences.create(
"prefs_name",
createMasterKey(),
App.appContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
Run Code Online (Sandbox Code Playgroud)
使用此功能创建主密钥
private fun createMasterKey(): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
} else {
val alias = "my_alias"
val start: Calendar = GregorianCalendar()
val end: Calendar = GregorianCalendar()
end.add(Calendar.YEAR, 30)
val spec = KeyPairGeneratorSpec.Builder(App.appContext)
.setAlias(alias)
.setSubject(X500Principal("CN=$alias"))
.setSerialNumber(BigInteger.valueOf(abs(alias.hashCode()).toLong()))
.setStartDate(start.time).setEndDate(end.time)
.build()
val kpGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(
"RSA",
"AndroidKeyStore"
)
kpGenerator.initialize(spec)
val kp: KeyPair …Run Code Online (Sandbox Code Playgroud) 我正在使用以下代码在我的应用程序中存储一些加密的信息。
val masterKey = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
"secret_shared_prefs",
masterKey,
this,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
Run Code Online (Sandbox Code Playgroud)
由于 MasterKeys 类在 Android 中已弃用,我应该使用 MasterKey 类,但我无法弄清楚获得相同定义的正确方法是什么。
有人可以显示与可用的 MasterKey 和 MasterKey.Builder 类的完全匹配吗?
下面的解决方案是这样工作的:
val spec = KeyGenParameterSpec.Builder(
"_androidx_security_master_key_",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(256)
.build()
val masterKey: MasterKey = MasterKey.Builder(this)
.setKeyGenParameterSpec(spec)
.build()
val sharedPreferences = EncryptedSharedPreferences.create(
this,
"secret_shared_prefs",
masterKey, // masterKey created above
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM);
Run Code Online (Sandbox Code Playgroud) 在我使用的其中一个应用程序中,我将重要的内容(令牌)存储到 EncryptedSharedPreferences(取自此处和此处):
/** 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: /sf/answers/4465669771/*/
object SecuredSharedPreferences {
private var cachedDefaultSharedPreferences: SharedPreferences? = null
/**warning: using this function can take some time (249 ms on Pixel 4, for example). Very recommended …Run Code Online (Sandbox Code Playgroud) 如何在加密共享首选项中使用密钥别名?下面是我的加密共享首选项
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
DEFAULT_MASTER_KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(DEFAULT_AES_GCM_MASTER_KEY_SIZE)
.build();
MasterKey masterKey = new MasterKey.Builder(this)
.setKeyGenParameterSpec(spec)
.build();
SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(this,
this.getResources().getString(R.string.app_preferences),
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
Run Code Online (Sandbox Code Playgroud)
我在实现这个时遇到了以下异常,
W/AndroidKeysetManager: keyset not found, will generate a new one
java.io.FileNotFoundException: can't read keyset; the pref value __androidx_security_crypto_encrypted_prefs_key_keyset__ does not exist
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.readPref(SharedPrefKeysetReader.java:71)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.readEncrypted(SharedPrefKeysetReader.java:89)
at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:105)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311)
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:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
Run Code Online (Sandbox Code Playgroud)
我需要替换DEFAULT_MASTER_KEY_ALIAS为该框中提到的密钥别名吗?如果是,那么我该如何在不进行硬编码的情况下做到这一点?
我已替换DEFAULT_MASTER_KEY_ALIAS为模块下项目结构中提到的关键别名。出现以下异常。
java.lang.IllegalArgumentException: KeyGenParamSpec's key alias does not match …Run Code Online (Sandbox Code Playgroud) 在 Android Kotlin 项目中,我使用androidx.security库基于此链接实现了 EncryptedSharedPreference 功能,并且它在调试模式下运行良好。但是在发布模式下,我不断收到此错误
java.lang.ExceptionInInitializerError
at com.package_name.i.a.f(:46)
at com.package_name.i.a.j(:52)
at com.package_name.i.a.e(:82)
at com.package_name.MyApplication.onCreate(:37)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
at android.app.ActivityThread.-wrap1(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
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.lang.RuntimeException: Field keySize_ for k.a.d.a.h0.u not found. Known fields are [private int k.a.d.a.h0.u.i, private static final k.a.d.a.h0.u k.a.d.a.h0.u.j, private static volatile k.a.d.a.i0.a.a1 k.a.d.a.h0.u.k]
at k.a.d.a.i0.a.v0.n0(:608)
Run Code Online (Sandbox Code Playgroud)
请分享您对如何解决此错误的想法。
如何使用https://developer.android.google.cn/reference/androidx/security/crypto/EncryptedSharedPreferences在我的 android java 应用程序中实现加密共享首选项?我不知道如何实施,有人可以帮忙吗?
java encryption android sharedpreferences encrypted-shared-preference
encrypted-shared-preference ×6
android ×4
encryption ×2
java ×2
security ×2
androidx ×1
kotlin ×1