仅 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 加密随机密钥。这称为混合加密。
我目前正在开发 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 加密随机密钥。这称为混合加密。