【问题标题】:Java encrypt file data and write it on same fileJava加密文件数据并将其写入同一个文件
【发布时间】:2016-04-16 01:47:21
【问题描述】:

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

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

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

这可能很愚蠢(这就是我寻求帮助的原因),所以这是我的方式

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 在他的回答中指出了一些重要的东西。我知道这种加密文件的方式是不安全的。我正在考虑防止too,是防止以后恢复文件。我的意思是,如果您曾经在硬盘中未加密,那么加密文件并将其保存在硬盘中是没有意义的!以我的经验,每次我恢复文件时,我都会对其进行最后一次编辑,但我永远无法获得更改历史记录。如果我一开始没有错,我想这一定是一样的。那我该如何帮助防止数据恢复呢?!

【问题讨论】:

  • 处理您所描述的操作的标准方法是创建一个新文件,将处理后的字节写入其中,然后删除输入文件。例如,参见gzip。在任何现代(日志式)文件系统上,无论如何您都不会就地覆盖数据;你根本无法控制它。
  • @chrylis 我知道这不是标准方式。我可以处理在其他目录中写入输出文件。正如我已经指出的那样,我有一些理由以非标准方式执行此操作(我肯定对此表示怀疑)。就像防止文件恢复以后访问普通(未加密)文件和其他...
  • 明白了,但是就地覆盖文件并不能做到这一点,所以这会带来很多麻烦。

标签: java encryption cryptography recovery data-recovery


【解决方案1】:

在读取时写入文件是可行的,但很容易引入会损坏文件的错误。为了安全起见,最好写入临时文件,然后删除原始文件并用临时文件替换它。这样一来,所有文件内容始终安全地保存在至少一个文件中。

关于这一点的一个警告是,如果您对现有文件进行加密,则无法保证原始文件仍不会记录在磁盘上。即使您在读取时写入相同的文件,相同的存储是否被加密数据覆盖也将取决于底层文件系统。

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

【讨论】:

  • 好吧,我在想这也可能不安全。你说的对。此外,写入文件时发生的任何意外(例如计算机关闭!!)都会损坏所有内容。感谢您提供有关覆盖的信息。我如何在加密时至少帮助保护数据恢复?!我想知道何时可以恢复数据,加密文件几乎没有用。以我的经验,每次我恢复文件时,我都会对其进行最后一次编辑,但我永远无法获得更改历史记录。我想这一定是一样的......
【解决方案2】:

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

bufferedInputStream.close();

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

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

希望有帮助:)

【讨论】:

  • 谢谢,这应该可行。但这不会同时处理所有三个动作(读取-加密-写入)同时发生。 (或者是吗??!)我正在寻找的是在读取文件时加密和写入......
猜你喜欢
  • 1970-01-01
  • 2015-01-27
  • 2015-09-18
  • 2014-06-02
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多