使用AES的对称加密会导致cipher.init上出现NullPointerException

问题描述 投票:1回答:1

我正在尝试使AES对称加密在我的android应用程序中正常工作,并且很难使其正常工作。

下面的示例代码

活动

override fun onCreate() {
  ...
  val key = KeyGenerator().generateSymemetricKey(ANDROID_KEYSTORE, "token", AES, PKCS7, CBC, PURPOSE_ENCRYPT or PURPOSE_DECRYPT)

  val encryptionPair = EncryptionHelper.encrypt(AES, "Testing", key)
  encryptionPair?.let {
    val decryptedString = EncryptionHelper.decrypt(AES, it.first, key, it.second)
    Timber.d(decryptedString)
  }
class KeyGenerator {
    fun generateSymemetricKey(keystoreName: String, alias: String, algorithm: String, padding: String, blockMode: String, purposes: Int): Key {

        val keystore = KeyStore.getInstance(keystoreName)
        keystore.load(null)

        if (!keystore.containsAlias(alias)) {
            val keyGenerator = KeyGenerator.getInstance(algorithm, keystoreName)


            val keyGenParameterSpec = KeyGenParameterSpec.Builder(alias, purposes)
                .setBlockModes(blockMode)
                .setEncryptionPaddings(padding)
                .build()

            keyGenerator.init(keyGenParameterSpec)

            return keyGenerator.generateKey()

        } else {

            return keystore.getKey(alias, null) as Key
        }
    }
}
object EncryptionHelper {

    fun encrypt(algorithm: String, text: String, key: Key): Pair<ByteArray, ByteArray>? = try {
        val cipher = Cipher.getInstance(algorithm)

        cipher.init(Cipher.ENCRYPT_MODE, key)

        val cipherText = cipher.doFinal(text.toByteArray())

        Pair(cipherText, cipher.iv)

    } catch (exception: GeneralSecurityException) {

        null
    }

    fun decrypt(algorithm: String, cipherText: ByteArray, key: Key, iv: ByteArray): String? = try {
        val cipher = Cipher.getInstance(algorithm)

        cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(iv))

        val plainText = cipher.doFinal(cipherText).toString()

        plainText

    } catch (exception: GeneralSecurityException) {
        null
    }
}

cipher.init中对encrypt的调用中,BouncyCastle引发以下异常

2020-01-09 17:05:13.743 24911-24911/com.smartrent.alloytile E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.smartrent.alloytile, PID: 24911
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartrent.alloytile/com.smartrent.alloytile.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3092)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3235)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6986)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
     Caused by: java.lang.NullPointerException: Attempt to get length of null array
        at com.android.org.bouncycastle.crypto.params.KeyParameter.<init>(KeyParameter.java:13)
        at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:692)
        at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:1076)
        at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2984)
        at javax.crypto.Cipher.tryCombinations(Cipher.java:2891)
        at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796)
        at javax.crypto.Cipher.chooseProvider(Cipher.java:773)
        at javax.crypto.Cipher.init(Cipher.java:1143)
        at javax.crypto.Cipher.init(Cipher.java:1084)
        at com.smartrent.crypto.EncryptionHelper.encrypt(EncryptionHelper.kt:17)
        at com.smartrent.alloytile.MainActivity.onCreate(MainActivity.kt:62)
        at android.app.Activity.performCreate(Activity.java:7326)
        at android.app.Activity.performCreate(Activity.java:7317)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3072)

在调试错误时,我发现key.encoded为空,这最终导致了问题。但是,这是我发现的所有教程都处理对称加密的方式,似乎没有人遇到此问题。

android kotlin aes android-keystore encryption-symmetric
1个回答
0
投票

在发布的代码中,会在Android keystore系统中生成一个密钥,以使用CBC模式和PKCS7填充进行AES加密。对于这个星座,必须将"AES/CBC/PKCS7Padding"作为参数传递给Cipher.getInstance(),如Android密钥库系统支持的密码的list所指定的那样。

© www.soinside.com 2019 - 2024. All rights reserved.