仅 Android 上的 RSA 加密中的 IllegalBlockSizeException

IllegalBlockSizeException in RSA encryption on Android only

我目前正在开发 Java-Cyrpto-API,稍后我想将其包含在 Android 应用程序中。我测试了我的 Crypto-API 的每个功能,在所有单元测试成功之后,我决定将我的 jar 包含到一个 Android 项目中。

在项目中,我开始生成一个 4096 位密钥对,以便将其添加到我的 class 中的一个对象中。

RSA.RSAKeyPair keyPair = null;

try {
   keyPair = RSA.generateKeyPair(4096);
} catch (IOException e) {
   e.printStackTrace();
}

self.setPrivateKey(keyPair.getPrivateKey());
self.setPublicKey(keyPair.getPublicKey());

之后,我在 API 中调用了一个函数,该函数使用 "self" 对象中的数据来加密一些数据。

应用程序在尝试使用 RSA 加密某些数据时抛出以下异常。

03-15 02:39:16.769    2394-2414/de.ifasec.instari E/Test﹕ javax.crypto.IllegalBlockSizeException: input must be under 512 bytes
        at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:245)
        at javax.crypto.Cipher.doFinal(Cipher.java:1340)
        at com.instari.encryption.RSA.encryptWithPublic(RSA.java:91)

我用 Google 来找出这里出了什么问题,只找到了关于无效密钥长度的帖子。我使用调试器获取我在应用程序中生成的所有键和值,以直接在我的 API 中测试它们。我的 API 测试成功,没有任何错误。

Android RSA 加密有任何限制或问题吗?

编辑:

private static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";

这是我的 encryptWithPublic() 方法:

// initialize
byte[] byteData = data.getBytes(); // convert string to byte array
PublicKey keyObject = extractPublicKey(publicKey);

// encrypt
Cipher cipher = null; // create conversion processing object
try {
    cipher = Cipher.getInstance(CIPHER_ALGORITHM);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
    e.printStackTrace();
    return null;
}

cipher.init(Cipher.ENCRYPT_MODE, keyObject); // initialize object's mode and key
byte[] encryptedByteData = cipher.doFinal(byteData); // use object for encryption

return Base64.encode(encryptedByteData);

RSA.RSAKeyPair 是一个简单的 class 我添加来存储密钥:

public static class RSAKeyPair{

    private String privateKey;
    private String publicKey;

    private RSAKeyPair(String privateKey, String publicKey) {
        this.privateKey = privateKey;
        this.publicKey = publicKey;
    }

    public String getPrivateKey() {
        return privateKey;
    }

    public String getPublicKey() {
        return publicKey;
    }
}

对象self与此类似。它只是 returns 我之前添加的键。

看来您只是想加密太多数据。可以使用带有 PKCS#1 填充的 RSA 加密的数据量是密钥大小(512 字节)减去 11 字节的填充开销,总共 501 字节。 Android 和 Java SE 都是如此。

对于 Java,"ECB" 部分用词不当。 RSA 不使用任何操作模式,所以它应该是 "None"。只有一个明文块将被加密。如果你想加密更多,你可以先生成一个随机的 AES 密钥,用它来加密消息,然后用 RSA 加密随机密钥。这称为混合加密。