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

2024-06-19

I use CipherOutputStream在java中对文件进行加密和解密,但是输入文件> 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. 没有实际的、适当的和secure加密模式/填充使用 RSA 加密大量数据(即这样做并不真正安全)。

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

如果您想了解更多关于为什么不应仅使用 RSA 来加密大量数据的详细信息,请参阅这两篇很棒的 stacktexchange 帖子:

  • 如何使用非对称加密(例如 RSA)来加密任意长度的明文? https://crypto.stackexchange.com/questions/14/how-can-i-use-asymmetric-encryption-such-as-rsa-to-encrypt-an-arbitrary-length/126#126
  • 类似 ECB 模式的 RSA 对于批量加密来说安全吗? https://crypto.stackexchange.com/questions/2789/is-rsa-in-a-ecb-like-mode-safe-for-bulk-encryption

如果要加密大量数据,标准方法是生成会话密钥(以密码方式使用一次的安全随机数)。您使用公钥加密会话密钥。然后,使用未加密的会话密钥通过对称算法(例如 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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何对文件进行加密和解密? 的相关文章

随机推荐