如何对文件进行加密和解密?

我在java中使用CipherOutputStream加密和解密文件,但输入文件> 117字节无法加密。 我使用RSA算法公钥长度为1024字节。

 cipher.init(Cipher.ENCRYPT_MODE, secKey); String cleartextFile = "cleartext.txt"; String ciphertextFile = "ciphertextSymm.txt"; FileInputStream fis = new FileInputStream(cleartextFile); FileOutputStream fos = new FileOutputStream(ciphertextFile); CipherOutputStream cos = new CipherOutputStream(fos, cipher); byte[] block = new byte[8]; int i; while ((i = fis.read(block)) != -1) { cos.write(block, 0, i); } cos.close(); 

如何加密input文件长度> 117字节?

您无法使用RSA加密文件,因为RSA(更准确地说,在Java中实现 RSA)不允许您加密比密钥长度更多的数据。 对于1024位密钥,您只能加密1024位,即128字节(实际上因填充原因而少一点)。

在所有情况下, 使用公钥算法 (非对称加密) 加密大量数据是不好的做法,原因有两个。

  1. 没有实用,适当和安全的加密模式/填充来使用RSA加密大量数据(即,这样做并不是真正安全)。

  2. 公钥算法要求大密钥是安全的(1024位,2048位),因此比对称密钥算法(仅需要128到256位密钥才能安全)慢得多。

如果您想了解更多有关不应仅使用RSA加密大量数据的原因的详细信息,请参阅以下两个很棒的stacktexchangepost:

  • 如何使用非对称加密(如RSA)加密任意长度的明文?
  • RSA是否类似于ECB模式可以安全地进行批量加密?

如果要加密大量数据,标准的继续方法是生成会话密钥(使用一次的加密安全随机数)。 您使用公钥加密会话密钥。 然后使用未加密的会话密钥使用对称算法(例如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();