Java加密文件数据并将其写入同一文件

时间:2016-01-11 16:47:07

标签: java encryption cryptography recovery data-recovery

我正在开发一个加密/解密文件的项目。因为这是我的第一次,我想知道我是否正确行事。到目前为止,我对加密的想法是这样的:

选择文件 - > 读取其所有字节并将其添加到字节数组 - > 加密字节数组 - > 将加密的字节写入同一文件。

请注意,在此项目中,输出文件与输入文件相同。所以我决定在将加密字节写入之前清除文件。

这可能是愚蠢的(这就是为什么我要求帮助),所以这是我的方式

public class Encryptor {
  File file;
  SecretKeySpec secretKeySpec;
  public void setFile(String filePath) throws Exception {
    this.file = new File(filePath);
    if(!file.isFile()){
      throw new Exception("The file you choosed is not valid");
    }
  }
  public void setKey(String keyword){
    try {
      MessageDigest sha = MessageDigest.getInstance("SHA-256");
      sha.update(keyword.getBytes("UTF-8"));
      byte[] key = sha.digest();
      secretKeySpec = new SecretKeySpec(key, "AES");
    } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
  }
  public void encrypt(){
    byte[] bFile = new byte[(int) file.length()];
    try {
      //adding portocol bytes to the file bytes
      //String portcol = "encryptor portocol";
      //byte[] decPortocol = portcol.getBytes();

      //convert file into array of bytes
      BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
      bufferedInputStream.read(bFile);
      bufferedInputStream.close();

      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      //outputStream.write(decPortocol);
      outputStream.write(bFile);

      byte[] cryptedFileBytes = outputStream.toByteArray();
      //Cipher and encrypting
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
      byte[] encryptedBytes = cipher.doFinal(cryptedFileBytes);

      //Write Encrypted File
      BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file,false));
      bufferedOutputStream.write(encryptedBytes);
      bufferedOutputStream.flush();
      bufferedOutputStream.close();
    }catch (Exception e){
      e.printStackTrace();
    }
  }

}

主要问题

还有其他方法可以同时在同一个文件上读取加密 - 写入吗?比如逐个部分地读取字节,同时加密该部分并用加密字节覆盖它。

你可以帮我更多吗?

此外,有关如何使我的加密文件更安全的任何信息也会有所帮助。

我的程序是否会杀死RAM?!

(注意)我出于某些原因在同一文件上写入加密数据。我不太熟悉硬盘的工作原理。我的一个原因是阻止文件以后恢复。有什么我必须知道的吗?我正在做什么阻止以后恢复未加密的文件?

修改 @erickson在他的回答中指出了一些重要的东西。我知道这种加密文件的方式并不安全。我正在考虑阻止太多,阻止了以后恢复文件。我的意思是没有必要加密文件并将其保存在你的硬盘中如果你曾经在那里取消加密!根据我的经验,每次我恢复文件时,我都会对其进行最后编辑,而且我永远无法获得更改的历史记录。如果我在第一时间没有错,我认为这必须是一样的。那我怎么能帮助防止数据恢复?!

2 个答案:

答案 0 :(得分:2)

在阅读时写入文件可以正常工作,但是引入一个会破坏文件的错误会很容易。为安全起见,最好写入临时文件,然后删除原始文件并将其替换为临时文件。这样,所有文件内容始终安全地存在于至少一个文件中。

有一点需要注意的是,如果您加密现有文件,则无法保证原始文件仍未记录在磁盘上。即使您在阅读时写入同一文件,是否使用加密数据覆盖相同的存储将取决于基础文件系统。

如果原始文件是以加密形式编写的,那会更好。即使编写应用程序不支持加密,大多数操作系统也支持创建加密文件系统,以便任何应用程序都可以保密文件。

答案 1 :(得分:1)

阅读完文件后,您需要关闭阅读器。您目前正在此行中执行此操作:

bufferedInputStream.close();

所以没关系。 然后,您只需使用以下命令覆盖它,而不是清除文件:

BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filename, false);

希望有所帮助:)