ahe*_*man 21 security android androidx encrypted-shared-preference
我决定使用来自 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 = kpGenerator.generateKeyPair()
kp.public.toString()
}
}
Run Code Online (Sandbox Code Playgroud)
我在某处找到了这个解决方案,但它没有得到验证(没有确认它确实有效),但它似乎应该有效。
将此代码块用于 API 21 和 22 时,在创建 EncryptedSharedPreferences 时出现错误,并显示:方法抛出“com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException”异常。协议消息包含无效标签(零)。
有人找到了这个实现的解决方案,或者你知道为什么会这样吗?我认为这会帮助很多人,因为没有确切的解释这个主密钥应该包含什么。
提前致谢!
小智 12
添加到清单
android:allowBackup="false" android:fullBackupContent="false"
因为卸载应用程序后,您仍然备份了加密文件,安装新版本后绝对无法解密。
Sea*_*ici 12
这是我所做的,它似乎已经修复了错误。不要删除自动备份功能,只需执行以下操作:
在AndroidManifest.xml中
android:allowBackup="true"
android:fullBackupContent="@xml/backup_descriptor"
Run Code Online (Sandbox Code Playgroud)
在 backup_descriptor.xml 中
<full-backup-content>
<exclude domain="sharedpref" path="keys.xml"/>
</full-backup-content>
Run Code Online (Sandbox Code Playgroud)
keys.xml 是加密的共享首选项文件名。通过这种方式排除所有加密的共享首选项文件。
另外,我正在使用实现 'androidx.security:security-crypto:1.1.0-alpha02'
目前看来,此设置一切正常。
Edm*_*son 11
我可以InvalidProtocolBufferException
通过两种方式解决这个问题,尽管我不喜欢其中任何一种:
使用旧版本security-crypto
implementation 'androidx.security:security-crypto:1.1.0-alpha01'
Run Code Online (Sandbox Code Playgroud)
使用最新(在撰写本文时)版本的security-crypto
,但使用强制旧版本的tink:
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
implementation('com.google.crypto.tink:tink-android') {
version {
strictly '1.4.0'
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
更新:不同设备上的错误。结果并不是解决办法。
我在清单中以这种方式设置了 android 属性“fullbackupcontent”
android:fullBackupContent="@xml/backup_descriptor"
Run Code Online (Sandbox Code Playgroud)
这是我的 backup_descriptor 文件
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<!-- App data isn't included in user's backup unless client-side encryption is enabled. -->
<include domain="file" path="." requireFlags="clientSideEncryption" />
<!-- Exclude specific shared preferences that contain GCM registration Id -->
<!-- <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]-->
<!-- path="string" />-->
</full-backup-content>
Run Code Online (Sandbox Code Playgroud)
现在我的应用程序再次运行并且我可以继续允许备份。
来源: https ://developer.android.com/guide/topics/data/autobackup#define-device-conditions
https://developer.android.com/guide/topics/data/autobackup#InclusionFiles