某些用户会遇到IllegalBlockSizeException

时间:2019-03-28 13:33:42

标签: android kotlin realm

我有一个使用Realm加密的Android应用。设置Realm加密时,很少有用户在启动过程中收到IllegalBlockSizeException的情况。

我们使用以下功能创建密钥:

private fun getOrGenerateKey() : ByteArray {
    val keyPair = getOrGenerateKeyPair()
    val prefs = applicationContext.getSharedPreferences(RealmPrefs, Context.MODE_PRIVATE)
    val cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding") // We need an algorithm supported on all android API levels

    // Try reading the encrypted AES key from the preferences
    val key = prefs.getString(RealmPrefsAES, null);

    if(key == null) {
        // No key was stored, generate a new byte array, encrypt then store:
        val keyBytes = ByteArray(64)
        SecureRandom().nextBytes(keyBytes)

        cipher.init(Cipher.ENCRYPT_MODE, keyPair.public)
        val encryptedBytes = cipher.doFinal(keyBytes)

        prefs.edit()
                .putString(RealmPrefsAES,  Base64.encodeToString(encryptedBytes, Base64.URL_SAFE))
                .apply()

        return keyBytes;
    }

    cipher.init(Cipher.DECRYPT_MODE, keyPair.private)
    return cipher.doFinal(Base64.decode(key.trim(), Base64.URL_SAFE))
}

@SuppressLint("InlinedApi")
private fun getOrGenerateKeyPair() : KeyPair {
    val keyStore = KeyStore.getInstance("AndroidKeyStore")
    keyStore.load(null);

    val keyEntry = keyStore.getEntry(RealmKeyAlias, null) as KeyStore.PrivateKeyEntry?

    if(keyEntry != null) {
        return KeyPair(
                keyEntry.certificate.publicKey,
                keyEntry.privateKey
        )
    }

    // If we got here, there was no key and we need to generate a new one. That is done differently in the API levels:
    return if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")

        kpg.initialize(KeyGenParameterSpec.Builder(
                RealmKeyAlias,
                KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                .build())

        kpg.generateKeyPair()
    } else {
        val start = Calendar.getInstance()
        val end = Calendar.getInstance()
        end.add(Calendar.YEAR, 100)

        @Suppress("DEPRECATION") // Deprecation handled by SDK version test
        val spec = KeyPairGeneratorSpec.Builder(applicationContext)
                .setAlias(RealmKeyAlias)
                .setSubject(X500Principal("CN=$RealmKeyAlias"))
                .setSerialNumber(BigInteger.ONE)
                .setStartDate(start.time)
                .setEndDate(end.time)
                .build()

        val kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore")

        kpg.initialize(spec)

        kpg.generateKeyPair()
    }
}

0 个答案:

没有答案