我通常在这里找到我们大多数问题的答案,但这次我需要问:-)。Android 8.0:IllegalBlocksizeException当使用RSA/ECB/OAEPWithSHA-512AndMGF1Padding
我们在Android 8.0(API级别26)上运行的其中一个应用程序中遇到了RSA加密/解密问题。
我们一直在使用RSA与“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”,它适用于Android 7.1以前的所有版本。在Android 8.0上运行的相同代码在调用Cipher.doFinal()时会抛出IllegalBlocksizeException。
下面是重现该问题的代码:
private KeyStore mKeyStore;
private static final String KEY_ALIAS = "MyKey";
void testEncryption() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyStoreException, IOException, CertificateException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, UnrecoverableEntryException, NoSuchPaddingException {
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
mKeyStore.load(null);
// Generate Key Pair -------------------------------------
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(
KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.setKeySize(2048)
.build());
KeyPair kp = kpg.generateKeyPair();
// Encrypt -----------------------------------------------
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)mKeyStore.getEntry(KEY_ALIAS, null);
PublicKey publicKey = (PublicKey) privateKeyEntry.getCertificate().getPublicKey();
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String x = "It doesn't have to be perfect, it's just for demonstration.";
byte [] vals = cipher.doFinal(x.getBytes("UTF-8"));
byte[] encryptedBytes = Base64.encode(vals, Base64.DEFAULT);
String encryptedText = new String(encryptedBytes, "UTF-8");
// Decrypt -----------------------------------------------
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
output.init(Cipher.DECRYPT_MODE, privateKey/*, spec */);
byte[] bxx = Base64.decode(encryptedText, Base64.DEFAULT);
byte[] bytes = output.doFinal(bxx); // <= throws IllegalBlocksizeException
String finalText = new String(bytes, 0, bytes.length, "UTF-8");
}
我试过其他填充算法了。 “RSA/ECB/OAEPWithSHA-1AndMGF1Padding”正常工作,而且“RSA/ECB/PKCS1Padding”正常工作。作为一种解决方法,我可以更改填充,但是从使用“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”的应用的先前版本进行更新时,这可能会导致问题,因为存储的数据无法再读取。
有没有人在这里相同的问题,也许一个想法如何解决它而不改变填充?
提前感谢和问候来自汉堡, 迪米特里
为什么你的标题说了一些与问题主体不同的东西? –
嗯?对不起,但它并没有完全不同。 SHA-256的结果与SHA-512的结果相同。 – Dimitri
是的,我也是。我认为它与AndroidKeyStore有关。如果你不能很快弄清楚,我会把它作为一个错误报告发送给Android。 –