Android API 21 创建自定义主密钥
Android API 21 Create Custom Master Key
我正在尝试创建加密的 SharedPreferences
实现,但 Android website 中给出的示例适用于 API 23 及更高版本。具体来说,问题是使用此代码创建主密钥 MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
。
在当前版本的 androidx 安全 ('androidx.security:security-crypto:1.1.0-alpha01') 上,您可以在技术上为 EncryptedSharedPreferences
创建实现,除了上面的 getOrCreate()
函数状态是针对 API仅限 23 岁及以上。因此,如果我理解正确的话,我唯一缺少的就是能够执行以下代码行:
private fun createSharedPref(context: Context): SharedPreferences {
return create(
"secret_shared_prefs",
masterKeyAlias,
context,
PrefKeyEncryptionScheme.AES256_SIV,
PrefValueEncryptionScheme.AES256_GCM
)
}
就是创建自己的自定义MasterKey。在 API 21 中有没有办法做到这一点?
到目前为止,我是这样编码的:
class SharedPreferencesUtil {
companion object {
private val masterKeyAlias = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
} else {
TODO("VERSION.SDK_INT < M")
//I need help here
}
private fun createSharedPref(context: Context): SharedPreferences {
return create(
"secret_shared_prefs",
masterKeyAlias,
context,
PrefKeyEncryptionScheme.AES256_SIV,
PrefValueEncryptionScheme.AES256_GCM
)
}
fun saveObject(context: Context, key: String, data: Any) {
val gson = Gson()
val json = gson.toJson(data)
val prefs = createSharedPref(context)
prefs.edit().putString(key, json).apply()
}
fun getJson(context: Context, key: String): String {
val prefs = createSharedPref(context)
val json = prefs.getString(key, "null")
return json!!
}
fun clearPreferences(context: Context) {
val prefs = createSharedPref(context).edit()
//remove my data
}
}
}
我找到了可行的解决方案 (source)
我将主密钥的实现替换为如下:
private fun createMasterKey(context: Context): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
} else {
val alias = "your_alias"
val start: Calendar = GregorianCalendar()
val end: Calendar = GregorianCalendar()
end.add(Calendar.YEAR, 30)
val spec =
KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setSubject(X500Principal("CN=$alias"))
.setSerialNumber(
BigInteger.valueOf(
Math.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()
}
}
我正在尝试创建加密的 SharedPreferences
实现,但 Android website 中给出的示例适用于 API 23 及更高版本。具体来说,问题是使用此代码创建主密钥 MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
。
在当前版本的 androidx 安全 ('androidx.security:security-crypto:1.1.0-alpha01') 上,您可以在技术上为 EncryptedSharedPreferences
创建实现,除了上面的 getOrCreate()
函数状态是针对 API仅限 23 岁及以上。因此,如果我理解正确的话,我唯一缺少的就是能够执行以下代码行:
private fun createSharedPref(context: Context): SharedPreferences {
return create(
"secret_shared_prefs",
masterKeyAlias,
context,
PrefKeyEncryptionScheme.AES256_SIV,
PrefValueEncryptionScheme.AES256_GCM
)
}
就是创建自己的自定义MasterKey。在 API 21 中有没有办法做到这一点?
到目前为止,我是这样编码的:
class SharedPreferencesUtil {
companion object {
private val masterKeyAlias = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
} else {
TODO("VERSION.SDK_INT < M")
//I need help here
}
private fun createSharedPref(context: Context): SharedPreferences {
return create(
"secret_shared_prefs",
masterKeyAlias,
context,
PrefKeyEncryptionScheme.AES256_SIV,
PrefValueEncryptionScheme.AES256_GCM
)
}
fun saveObject(context: Context, key: String, data: Any) {
val gson = Gson()
val json = gson.toJson(data)
val prefs = createSharedPref(context)
prefs.edit().putString(key, json).apply()
}
fun getJson(context: Context, key: String): String {
val prefs = createSharedPref(context)
val json = prefs.getString(key, "null")
return json!!
}
fun clearPreferences(context: Context) {
val prefs = createSharedPref(context).edit()
//remove my data
}
}
}
我找到了可行的解决方案 (source)
我将主密钥的实现替换为如下:
private fun createMasterKey(context: Context): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
} else {
val alias = "your_alias"
val start: Calendar = GregorianCalendar()
val end: Calendar = GregorianCalendar()
end.add(Calendar.YEAR, 30)
val spec =
KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setSubject(X500Principal("CN=$alias"))
.setSerialNumber(
BigInteger.valueOf(
Math.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()
}
}