Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android KeyStoreException未知错误大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在用户通过 Android M指纹API进行身份验证后解密加密文本.我一直在尝试遵循 Android Security samples,以及 KeyGenParameterSpec文档中提供的示例.我已经能够使用公钥成功加密文本,但是当我使用DECRYPT_MODE中的私钥使用Cipher调用cipher.doFinal时,我收到KeyStoreException“UnkNown Error”
03-15 10:06:58.074 14702-14702/com.example.app E/LoginFragment: Failed to decrypt password
        javax.crypto.IllegalBlockSizeException
            at android.security.keystore.AndroidKeyStoreCipherSpiBase.ENGIneDoFinal(AndroidKeyStoreCipherSpiBase.java:486)
            at javax.crypto.Cipher.doFinal(Cipher.java:1502)
            at com.example.app.ui.fragment.util.LoginFragment.onAuthenticationSucceeded(LoginFragment.java:251)
            at com.example.app.ui.controller.FingerprintCallBACk.onAuthenticationSucceeded(FingerprintCallBACk.java:21)
            at android.support.v4.hardware.fingerprint.FingerprintManagerCompat$Api23FingerprintManagerCompatImpl$1.onAuthenticationSucceeded(FingerprintManagerCompat.java:301)
            at android.support.v4.hardware.fingerprint.FingerprintManagerCompatApi23$1.onAuthenticationSucceeded(FingerprintManagerCompatApi23.java:96)
            at android.hardware.fingerprint.FingerprintManager$MyHandler.sendAuthenticatedSucceeded(FingerprintManager.java:805)
            at android.hardware.fingerprint.FingerprintManager$MyHandler.handlemessage(FingerprintManager.java:757)
            at android.os.Handler.dispatchmessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    Caused by: android.security.KeyStoreException: UnkNown error
            at android.security.KeyStore.getKeyStoreException(KeyStore.java:632)
            at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
            at android.security.keystore.AndroidKeyStoreCipherSpiBase.ENGIneDoFinal(AndroidKeyStoreCipherSpiBase.java:473)
            at javax.crypto.Cipher.doFinal(Cipher.java:1502) 
            at com.example.app.ui.fragment.util.LoginFragment.onAuthenticationSucceeded(LoginFragment.java:251) 
            at com.example.app.ui.controller.FingerprintCallBACk.onAuthenticationSucceeded(FingerprintCallBACk.java:21) 
            at android.support.v4.hardware.fingerprint.FingerprintManagerCompat$Api23FingerprintManagerCompatImpl$1.onAuthenticationSucceeded(FingerprintManagerCompat.java:301) 
            at android.support.v4.hardware.fingerprint.FingerprintManagerCompatApi23$1.onAuthenticationSucceeded(FingerprintManagerCompatApi23.java:96) 
            at android.hardware.fingerprint.FingerprintManager$MyHandler.sendAuthenticatedSucceeded(FingerprintManager.java:805) 
            at android.hardware.fingerprint.FingerprintManager$MyHandler.handlemessage(FingerprintManager.java:757) 
            at android.os.Handler.dispatchmessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:148) 
            at android.app.ActivityThread.main(ActivityThread.java:5417) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

相关的当前代码如下:

public KeyStore getKeyStore() {
    try {
        return KeyStore.geTinstance("AndroidKeyStore");
    } catch (KeyStoreException exception) {
        throw new RuntimeException("Failed to get an instance of KeyStore",exception);
    }
}

public KeyPairGenerator getKeyPairGenerator() {
    try {
        return KeyPairGenerator.geTinstance("RSA","AndroidKeyStore");
    } catch(NoSuchAlgorithmException | NoSuchProviderException exception) {
        throw new RuntimeException("Failed to get an instance of KeyPairGenerator",exception);
    }
}

public Cipher getCipher() {
    try {
        return Cipher.geTinstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
    } catch(NoSuchAlgorithmException | NoSuchPaddingException exception) {
        throw new RuntimeException("Failed to get an instance of Cipher",exception);
    }
}

private void createKeyPair() {
    try {
        mKeyPairGenerator.initialize(
                new KeyGenParameterSpec.builder(KEY_ALIAS,KeyProperties.PURPOSE_DECRYPT)
                        .setDigests(KeyProperties.DIGEST_SHA256,KeyProperties.DIGEST_SHA512)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEp)
                        .setUserAuthenticationrequired(true)
                        .build());
        mKeyPairGenerator.generateKeyPair();
    } catch(InvalidAlgorithmParameterException exception) {
        throw new RuntimeException("Failed to generate key pair",exception);
    }
}

private Boolean initCipher(int opmodE) {
    try {
        mKeyStore.load(null);

        if(opmode == Cipher.ENCRYPT_MODE) {
            PublicKey key = mKeyStore.getCertificate(KEY_ALIAS).getPublicKey();

            PublicKey unreStricted = KeyFactory.geTinstance(key.getAlgorithm())
                    .generatePublic(new X509EncodedKeySpec(key.getEncoded()));

            mCipher.init(opmode,unreStricted);
        } else {
            PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_ALIAS,null);
            mCipher.init(opmode,key);
        }

        return true;
    } catch (KeyPeRMANentlyInvalidatedException exception) {
        return false;
    } catch(KeyStoreException | CertificateException | UnrecoverableKeyException
            | IOException | NoSuchAlgorithmException | InvalidKeyException
            | InvalidAlgorithmParameterException exception) {
        throw new RuntimeException("Failed to initialize Cipher",exception);
    }
}

private void encrypt(String password) {
    try {
        initCipher(Cipher.ENCRYPT_MODE);
        byte[] bytes = mCipher.doFinal(password.getBytes());
        String encryptedpassword = Base64.encodeToString(bytes,Base64.NO_WRAp);
        mPreferences.getString("password").set(encryptedpassword);
    } catch(IllegalBlockSizeException | BadPaddingException exception) {
        throw new RuntimeException("Failed to encrypt password",exception);
    }
}

private String decrypt(Cipher cipher) {
    try {
        String encryptedpassword = mPreferences.getString("password").get();
        byte[] bytes = Base64.decode(encryptedpassword,Base64.NO_WRAp);
        return new String(cipher.doFinal(bytes));
    } catch (IllegalBlockSizeException | BadPaddingException exception) {
        throw new RuntimeException("Failed to decrypt password",exception);
    }
}

什么可能导致这个“未知错误”?我已经排除了setUserAuthenticationrequired,但我无法弄清楚是什么原因引起的.我也尝试使用全局mCipher而不是FragmentManagerCompat.AuthenticationCallBACk.onAuthenticationSucceeded(尽管我认为它们应该是同一个)提供的密码具有相同的结果.

我在寻找another one of my questions的答案时遇到了这个问题.

解决方法

我在 Android Issue Tracker找到了答案;根据我的理解,为了解决一个 known issue而创建的不受限制的PublicKey变得与当前的密码不兼容.解决此问题的方法是在初始化密码时指定OAEPParameterSpec:
OAEPParameterSpec spec = new OAEPParameterSpec(
        "SHA-256","MGF1",MGF1ParameterSpec.SHA1,Psource.PSpecified.DEFAULT);

mCipher.init(opmode,unreStricted,spec);

大佬总结

以上是大佬教程为你收集整理的Android KeyStoreException未知错误全部内容,希望文章能够帮你解决Android KeyStoreException未知错误所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。