Android API 21 Создать собственный мастер-ключ - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь создать зашифрованную реализацию SharedPreferences, но пример, приведенный на Android веб-сайте , предназначен для 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
        }
    }
}

1 Ответ

0 голосов
/ 18 июня 2020

Я нашел рабочее решение ( исходник )

Я заменил свою реализацию мастер-ключа следующим образом:

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()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...