Java 仅Android上RSA加密中的非法BlockSizeException

Java 仅Android上RSA加密中的非法BlockSizeException,java,android,encryption,cryptography,Java,Android,Encryption,Cryptography,我目前正在开发一个JavaCyrptoAPI,我想稍后将其包含在Android应用程序中。我测试了我的加密API的每个功能,在所有单元测试成功后,我决定将我的jar包含到一个Android项目中 在这个项目中,我开始生成一个4096位的密钥对,以便将其添加到类中的一个对象中 RSA.RSAKeyPair keyPair = null; try { keyPair = RSA.generateKeyPair(4096); } catch (IOException e) { e.pri

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

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

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

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

编辑: 这是我的encryptWithPublic()方法:

RSA.RSAKeyPair是一个简单的i类,用于存储密钥:

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;
    }
}

对象本身与此类似。它只是返回我之前添加的密钥。

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


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

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


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

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


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

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



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

请向我们展示您在
密码
实例中使用RSA公钥的代码,以及实例的创建。对此,我深表歉意!我更新了我的帖子。好的,谢谢。下一个问题:什么是
RSA.RSAKeyPair
self
?这是Java代码,对吗?我又更新了。是的,当然都是用Java编写的。请向我们展示您在
密码
实例中使用RSA公钥的代码,以及实例的创建。非常抱歉!我更新了我的帖子。好的,谢谢。下一个问题:什么是
RSA.RSAKeyPair
self
?这是Java代码,对吗?我又更新了。是的,当然都是用Java编写的。请向我们展示您在
密码
实例中使用RSA公钥的代码,以及实例的创建。非常抱歉!我更新了我的帖子。好的,谢谢。下一个问题:什么是
RSA.RSAKeyPair
self
?这是Java代码,对吗?我又更新了。是的,当然都是用Java编写的。请向我们展示您在
密码
实例中使用RSA公钥的代码,以及实例的创建。非常抱歉!我更新了我的帖子。好的,谢谢。下一个问题:什么是
RSA.RSAKeyPair
self
?这是Java代码,对吗?我又更新了。是的,当然都是Java的。谢谢你的回答!我以前就知道这一点。看到这个错误后,我认为Android会有一个限制或类似的限制,限制您可以加密或解密的数据量。事实证明,我使用的getData()函数返回了错误的值,这些值比我预期的要大得多。是的,我有点走错路了——看起来你也是——因为我看到了运行时的差异。问题真的摆在我们面前:)PS当心围绕已经存在的功能的通用包装类;它们通常弊大于利(这看起来像一个包装类)。谢谢你的回答!我以前就知道这一点。看到这个错误后,我认为Android会有一个限制或类似的限制,限制您可以加密或解密的数据量。结果是
// 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);
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;
    }
}