您不能使用 RSA 加密文件,因为 RSA(更准确地说,是 RSA 在 Java 中的实现)不允许您加密比密钥长度更多的数据。对于 1024 位密钥,您只能加密 1024 位,即 128 字节(实际上由于填充原因要少一些)。
在所有情况下,使用公钥算法(非对称加密)加密大量数据都是不好的做法,主要有两个原因。
使用 RSA 加密大量数据并不实用、适当且安全的加密模式/填充(即,这样做并不安全)。
公钥算法需要一个大密钥来保证安全(1024 位、2048 位),因此比对称密钥算法(只需要 128 到 256 位的密钥就可以保证安全)慢得多。
如果您想了解有关为什么不应该单独使用 RSA 加密大量数据的更多详细信息,请参阅这两个出色的 stacktexchange 帖子:
如果你想加密大量数据,标准的做法是生成一个会话密钥(一个使用过一次的加密安全随机数)。您使用公钥加密会话密钥。然后,您使用未加密的会话密钥使用对称算法(例如 AES)加密文件(大量数据)。然后,您将加密的会话密钥和加密的数据一起存储在最终文件中。这就是 PGP(或 GnuPG)在发送加密邮件时进行的方式。SSL/TLS 也以类似的方式工作。
最后,正确使用密码学是复杂的(几乎任何事情都可能造成安全漏洞:加密模式、填充等......)所以我建议你要非常小心,并确保你的代码将由熟悉的人审查加密很重要。
这是一段显示一般过程的代码:
// 1. Generate a session key
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128)
SecretKey sessionKey = keyGen.generateKey();
// 2. Encrypt the session key with the RSA public key
Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey)
byte[] encryptedSessionKey = rsaCipher.doFinal(sessionKey.getEncoded());
// 3. Encrypt the data using the session key (unencrypted)
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, sessionKey); <-- sessionKey is the unencrypted
// session key.
// ... use aesCipher to encrypt your data
// 4. Save the encrypted data along with the encrypted
// session key (encryptedSessionKey).
// PLEASE NOTE THAT BECAUSE OF THE ENCRYPTION MODE (CBC),
// YOU ALSO NEED TO ALSO SAVE THE IV (INITIALIZATION VECTOR).
// aesCipher.aesCipher.getParameters().
// getParametersSpec(IvParameters.class).getIV();