在 java 中使用 rsa 加密和解密大文件

encrypting and decryption large file using rsa in java

我正在使用 RSA 算法对大小超过 rsa 密钥大小的文件进行加密和解密。

在下面的加密代码中,我正在逐块读取文件内容并将其转换为密文。块大小为 32 字节。

FileInputStream fin1 = new FileInputStream(genfile);

FileOutputStream fout = new FileOutputStream(seedcipher);

byte[] block = new byte[32];
int i;
while ((i = fin1.read(block)) != -1)
{
    byte[] inputfile= cipher.doFinal(block);
    fout.write(inputfile);
}

fin1.close();

在解密部分,在我提到的块大小为 128 字节的代码中进行了相同的块式解密

FileInputStream fin1 = new FileInputStream(encryptedfile);
FileOutputStream fout = new FileOutputStream(seedcipher);

DataInputStream dos =new DataInputStream(fin1);
DataOutputStream dosnew =new DataOutputStream(fout);
byte[] block = new byte[128];
int i;
while ((i = fin1.read(block)) != -1)
{
    byte[] inputfile= cipher.doFinal(block);
      fout.write(inputfile);
}

输入文件大小为 81.3 kB,文件包含

0
1
2
3
4.....29000 

文件解密后,输出包含一些不相关的额外值。为什么结果中有额外的数据?

你可以通过游程编码来解决这个问题。使用 DataOutputStream 在开头写入一个整数,表示之后写入的字节数。解密时,读取那个整数,只使用它说的字节数。

我注意到您正在使用更新方法的 Cipher class in a wrong way. Use the update method to add bytes to cipher and only use doFinal once. It is important that you use this 重载版本。将 inputOffset 参数设置为零,将 inputLen 参数设置为 i。这将确保 Cipher 只使用它应该使用的字节。

参见 JB Nizets 的回答。

您逐块读取的IO代码不正确:

while ((i = fin1.read(block)) != -1) {
    byte[] inputfile= cipher.doFinal(block);
    fout.write(inputfile);
}
  1. 它假定每次你要求读取一个块时,都会读取整个块。不一定如此。可能只读取几个字节。实际读取的字节数由 read() 方法返回(并存储在 i 中)。你不应该忽视它。
  2. 最后一个块很可能不完整,除非你的文件大小是 32 的倍数。所以在最后一次迭代中,你加密文件的最后 N 个剩余字节 + 32 - N上一次迭代时存储在字节数组中的字节数。

使用 RSA 加密大文件不是一个好主意。例如,您可以生成一个随机 AES 密钥,使用 RSA 对其进行加密并将其存储在输出文件中,然后使用 AES 对文件本身进行加密,这样速度要快得多,并且对于大输入没有任何问题。解密将读取加密的 AES 密钥,对其进行解密,然后使用 AES 对文件的其余部分进行解密。

混合密码系统

示例:对于 1024 位密钥,您可以加密大约 1024 / 8 = 128 字节
注意:准确值为 128 字节 - 11 字节用于填充

您可以使用对称密钥加密和解密要传输的数据(> 128 字节)。 RSA 只能将数据加密到一定程度(例如 128 字节),这取决于 RSA 密钥长度。

这意味着如果你想传输任何大于 128 字节的东西,你必须先传输一个小于 128 字节的对称密钥,这样你就可以有以下内容:

  1. Generate a symmetric key (< 128 bytes)
  2. Encrypt symmetric key with RSA
  3. Transfer encrypted symmetric key
  4. Decrypt symmetric key with RSA
  5. Encrypt data (> 128 bytes) with symmetric key
  6. Transfer encrypted data
  7. Decrypt encrypted data with symmetric key

或(同时传输加密对称密钥和加密数据)

  1. Generate a symmetric key (< 128 bytes)
  2. Encrypt symmetric key with RSA
  3. Encrypt data (> 128 bytes) with symmetric key
  4. Transfer encrypted symmetric key & encrypted data
  5. Decrypt symmetric key with RSA
  6. Decrypt encrypted data with symmetric key

有关详细信息,请单击 here (Hybrid cryptosystem)