嗨,这是同一个问题,两年前被问过: Java/JCE: Decrypting “long” message encrypted with RSA
我有一个大字节数组和rsa密钥对,由值1024启动。 使用rsa加密和密钥的指定大小是强烈要求,我无法改变它。所以我不能使用非对称加密对称密钥进行对称加密。我不能使用任何其他键。我有一个字节数组,需要返回加密的字节数组。我想知道是否有任何现成的工具,可以解决这个问题?
很抱歉这样一个业余的问题,但我真的需要帮助。
答案 0 :(得分:12)
如上所述,您的问题只有一个答案,那就是“不”。 RSA加密是一种算法,它对给定大小的消息进行加密,这取决于密钥大小;使用1024位RSA密钥和RSA the standard描述它,最大大小为117字节,不再多。单独使用RSA无法加密更大的消息,这是一个明确的数学确定性。
如果您确实需要处理更长的邮件,那么必然必须添加其他内容。在这种情况下,请请,不要尝试做任何你自己设想的事情,用一些非常聪明的数据分成小块等。那条道路导致厄运。您可能会生成一些出现来编译和运行的东西,但在某种程度上它总是很弱,就像几乎所有其他自制的密码学变体一样。这是因为无法测试安全性:它不是“工作”或“不工作”的情况。
非对称加密的良好路径因此:
"AES/CBC/PKCS5Padding"
)使用 K 加密邮件。由于这是一次性密钥,因此您可以使用全零IV。这会产生一堆字节,我们称之为 F 。解密以相反的顺序进行:RSA私钥用于从 E 恢复 K ,然后 K 用于解密< em> F 进入原始邮件。密钥 K 永远不会存储在任何地方,并且每次都会生成新密钥K (即使您将相同的消息加密两次)。这很重要,除非你明白自己在做什么,否则不要改变它(如果你这样做,那么你就已经知道了。)
鉴于您对问题的陈述, 除了“只是RSA”之外还要做其他事情。我上面描述的程序是关于你可以提出的最好的“其他东西”,安全方面。
将一些加密元素组装到这样的协议中是一个充满陷阱的过程,因此您可以使用已定义的格式和支持库获得更好的运气。非对称加密的两种常见格式是CMS和OpenPGP。一个支持这两个并且声誉良好的图书馆是Bouncy Castle。
答案 1 :(得分:1)
如果您确实需要使用RSA加密/解密长字符串,那么您可以将字节分解为较小的“块”,并一次一个地通过密码处理每个字节块,同时将结果存储在ByteBuffer中。
<强>加密强>
byte[] encData = null;
try {
// create public key
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(key);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(publicKeySpec);
Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
pkCipher.init(Cipher.ENCRYPT_MODE, pk);
int chunkSize = 117; // 1024 / 8 - 11(padding) = 117
int encSize = (int) (Math.ceil(data.length/117.0)*128);
int idx = 0;
ByteBuffer buf = ByteBuffer.allocate(encSize);
while (idx < data.length) {
int len = Math.min(data.length-idx, chunkSize);
byte[] encChunk = pkCipher.doFinal(data, idx, len);
buf.put(encChunk);
idx += len;
}
// fully encrypted data
encData = buf.array();
} catch (Exception e) {
e.printStackTrace();
解密
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.DECRYPT_MODE, rsaPk);
int chunkSize = 128;
int idx = 0;
ByteBuffer buf = ByteBuffer.allocate(data.length);
while(idx < data.length) {
int len = Math.min(data.length-idx, chunkSize);
byte[] chunk = rsaCipher.doFinal(data, idx, len);
buf.put(chunk);
idx += len;
}
// fully decrypted data
byte[] decryptedData = buf.array();