android - 使用 Android 指纹时出现问题 : IV required when decrypting. 使用 IvParameterSpec 或 AlgorithmParameters 提供

标签 android encryption

我正在关注 ConfirmCredential Google 提供的 Android 示例,但它仅显示如何加密数据。当我尝试解密它时出现异常:

java.security.InvalidKeyException: IV required when decrypting. Use IvParameterSpec or AlgorithmParameters to provide it.

我使用以下代码:

String transforation = KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7;

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);

// encrypt
Cipher cipher = Cipher.getInstance(transforation);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String encriptedPassword = cipher.doFinal("Some Password".getBytes("UTF-8"));

// decrypt
cipher = Cipher.getInstance(transforation);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String password = new String(cipher.doFinal(encriptedPassword), "UTF-8"));

异常在以下行抛出:

cipher.init(Cipher.DECRYPT_MODE, secretKey);

知道在这种情况下进行解密的正确方法是什么吗?

最佳答案

基本上,您必须为解密模式传递 IvParameterSpec,而您不应手动将其设置为加密模式。

这就是我所做的并且效果很好:

private initCipher(int mode) {
    try {
        byte[] iv;
        mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        IvParameterSpec ivParams;
        if(mode == Cipher.ENCRYPT_MODE) {
            mCipher.init(mode, generateKey());
            ivParams = mCipher.getParameters().getParameterSpec(IvParameterSpec.class);
            iv = ivParams.getIV();
            fos = getContext().openFileOutput(IV_FILE, Context.MODE_PRIVATE);
            fos.write(iv);
            fos.close();
        }
        else {
            key = (SecretKey)keyStore.getKey(KEY_NAME, null);
            File file = new File(getContext().getFilesDir()+"/"+IV_FILE);
            int fileSize = (int)file.length();
            iv = new byte[fileSize];
            FileInputStream fis = getContext().openFileInput(IV_FILE);
            fis.read(iv, 0, fileSize);
            fis.close();
            ivParams = new IvParameterSpec(iv);
            mCipher.init(mode, key, ivParams);
        }
        mCryptoObject = new FingerprintManager.CryptoObject(mCipher);
    } catch(....)
}

您还可以使用 Base64 对 IV 数据进行编码并将其保存在共享首选项下,而不是将其保存在文件下。

无论哪种情况,如果您为 Android M 使用了新的完整备份功能,请记住,不应允许此数据备份/恢复,因为当用户重新安装应用程序或在另一台设备上安装该应用程序。

关于android - 使用 Android 指纹时出现问题 : IV required when decrypting. 使用 IvParameterSpec 或 AlgorithmParameters 提供,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33214469/

相关文章:

java - "Wrong algorithm"尝试在 Java 中解密时出错

cryptography - 是否存在加密和解密可以按任意顺序进行的安全加密算法?

c# - 创建大量数字的库或方法

java - 带有清除按钮的 Android java android.support.design.widget.TextInputLayout

Android HTTP GET 参数

android - 使用 root 访问权限在 Android 上打开另一个应用程序的 sqlite 数据库

Android Webview 在 4.4 上卡住,nativeOnDraw 失败;清除为背景颜色

file - Python将文本文件读取为二进制文件?

python - 哈希函数不会为相同的输入返回相同的输出

java - 我希望我的计时器在后台运行,但它一旦进入后台 android 就会停止