簡體   English   中英

Android N InvalidKeyException

[英]Android N InvalidKeyException

我有一個仍面向Android 6.0的應用程序,但是嘗試在Android N上安裝時遇到加密錯誤(我也嘗試了N。 這是堆棧跟蹤:

W/System.err: java.security.InvalidKeyException: Algorithm requires a PBE key
W/System.err:     at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:564)
W/System.err:     at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:1006)
W/System.err:     at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2977)
W/System.err:     at javax.crypto.Cipher.tryCombinations(Cipher.java:2884)
W/System.err:     at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2789)
W/System.err:     at javax.crypto.Cipher.chooseProvider(Cipher.java:956)
W/System.err:     at javax.crypto.Cipher.init(Cipher.java:1199)
W/System.err:     at javax.crypto.Cipher.init(Cipher.java:1143)

如您所見,它在調用Cipher.init時發生。 這是我的aesDecrypt方法:

public static String aesDecrypt(String data, String password) {
    try {
        String aesKey = getAesKey(password);
        byte[] keyValue = Base64.decode(aesKey, Base64.NO_WRAP);
        SecretKey key = new SecretKeySpec(keyValue, "AES");
        Cipher c = Cipher.getInstance(AES_ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] dataB = Base64.decode(data, Base64.NO_WRAP);
        byte[] decVal = c.doFinal(dataB);
        return new String(decVal);
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }
    return null;
}

和我的getAesKey:

private static String getAesKey(String password) {
    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(password.getBytes("UTF-8"));
        return Base64.encodeToString(hash, Base64.NO_WRAP);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

我已經驗證了我在c.init中傳遞的密鑰不為null。 為什么這在運行7.0的手機上不起作用?


[評論編輯]

上面的代碼使用:

 AES_ALGO = "PBEWITHSHA256AND128BITAES-CBC-BC";

您唯一沒有顯示給我們的是AES_ALGO的值,這很可能表示PBE加密,該密鑰不是使用任何類型的PBE密鑰派生(例如PBKDF1或PBKDF2)生成的。 這些密鑰將返回與"AES"不同的密鑰算法類型。

顯然,在這方面,不同版本的Android之間存在差異。 這並不是Android提供商第一次在使用上有所不同,因為它們會定期更改實施。 API仍然相同,但是算法的實現有所不同。

要使用PBC加密方法所使用的CBC模式加密進行加密,請查看使用"AES/CBC/PKCS5Padding"的無數示例。 不要忘記,您需要正確處理IV值,這是Bouncy Castle PBE密碼本身所包含的。


[編輯]

令我驚訝的是,由BC“計算”的PBE密鑰僅包含PBE規范的密碼和迭代計數。 計算的值僅是與密碼一起使用的util。 密鑰的類型不僅是SecretKey而且:

org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey

它還包含例如IV值的占位符。 因此,該計算當前根本不起作用也就不足為奇了。 更令人驚訝的是,它似乎曾經奏效過。

這個故事的寓意是,不要隨意混合使用Ciphers和SecretKeys。 它可能適用於特定版本,但是當開發人員決定執行更嚴格的檢查時,代碼可能會消失。

我嘗試僅使用PBE算法的名稱作為密鑰,但是顯然這永遠行不通。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM