Android 31:java.security.InvalidKeyException:密钥大小未知

lokaqttq  于 2023-03-28  发布在  Android
关注(0)|答案(1)|浏览(234)

我正在编写一个处理RSA密钥的android程序。私钥(长度2048)是从字节数组导入的(不是由设备生成的)。如果我使用Android Studio Emulator API 31,该密钥可以毫无问题地使用。但是在Pixel 3硬件API 31上,有一个例外。原因是什么?

----- DEVICE -----
Brand: google
Device: blueline
Model: Pixel 3
ID: SP1A.210812.016.C2
Product: blueline

----- ANDROID OS -----
Android SDK: 31
Android release: 12
Android incremental: 8618562

堆栈跟踪:

03-22 22:46:03.611 23770 23770 W System.err: java.security.InvalidKeyException: Size of key not known
03-22 22:46:03.611 23770 23770 W System.err: at android.security.keystore2.AndroidKeyStoreRSACipherSpi.initKey(AndroidKeyStoreRSACipherSpi.java:451)
03-22 22:46:03.611 23770 23770 W System.err: at android.security.keystore2.AndroidKeyStoreCipherSpiBase.init(AndroidKeyStoreCipherSpiBase.java:256)
03-22 22:46:03.611 23770 23770 W System.err: at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:168)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2985)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher.tryCombinations(Cipher.java:2892)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2797)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher.chooseProvider(Cipher.java:774)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher.init(Cipher.java:1144)
03-22 22:46:03.611 23770 23770 W System.err: at javax.crypto.Cipher.init(Cipher.java:1085)
pzfprimi

pzfprimi1#

@Override
protected final void initKey(int opmode, Key key) throws InvalidKeyException {
    if (key == null) {
        throw new InvalidKeyException("Unsupported key: null");
    }
    if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) {
        throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
                + ". Only " + KeyProperties.KEY_ALGORITHM_RSA + " supported");
    }
    AndroidKeyStoreKey keystoreKey;
    if (key instanceof AndroidKeyStorePrivateKey) {
        keystoreKey = (AndroidKeyStoreKey) key;
    } else if (key instanceof AndroidKeyStorePublicKey) {
        keystoreKey = (AndroidKeyStoreKey) key;
    } else {
        throw new InvalidKeyException("Unsupported key type: " + key);
    }

    if (keystoreKey instanceof PrivateKey) {
        // Private key
        switch (opmode) {
            case Cipher.DECRYPT_MODE:
            case Cipher.UNWRAP_MODE:
                // Permitted
                break;
            case Cipher.ENCRYPT_MODE:
            case Cipher.WRAP_MODE:
                if (!adjustConfigForEncryptingWithPrivateKey()) {
                    throw new InvalidKeyException(
                            "RSA private keys cannot be used with " + opmodeToString(opmode)
                            + " and padding "
                            + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
                            + ". Only RSA public keys supported for this mode");
                }
                break;
            default:
                throw new InvalidKeyException(
                        "RSA private keys cannot be used with opmode: " + opmode);
        }
    } else {
        // Public key
        switch (opmode) {
            case Cipher.ENCRYPT_MODE:
            case Cipher.WRAP_MODE:
                // Permitted
                break;
            case Cipher.DECRYPT_MODE:
            case Cipher.UNWRAP_MODE:
                throw new InvalidKeyException(
                        "RSA public keys cannot be used with " + opmodeToString(opmode)
                        + " and padding "
                        + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
                        + ". Only RSA private keys supported for this opmode.");
                // break;
            default:
                throw new InvalidKeyException(
                        "RSA public keys cannot be used with " + opmodeToString(opmode));
        }
    }

    long keySizeBits = -1;
    for (Authorization a : keystoreKey.getAuthorizations()) {
        if (a.keyParameter.tag == KeymasterDefs.KM_TAG_KEY_SIZE) {
            keySizeBits = KeyStore2ParameterUtils.getUnsignedInt(a);
        }
    }

    if (keySizeBits == -1) {
        throw new InvalidKeyException("Size of key not known");
    } else if (keySizeBits > Integer.MAX_VALUE) {
        throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
    }
    mModulusSizeBytes = (int) ((keySizeBits + 7) / 8);

    setKey(keystoreKey);
}

转到AndroidKeyStoreRSACipherSpi的API级别31源代码(如上所示),并在它抛出InvalidKeyException并显示消息“Key的大小未知”之前设置断点。比较Pixel 3和模拟器上的运行。检查其中有什么区别。

相关问题