2016-01-11 72 views
1

我正在开发一个项目来加密/解密文件。因为这是我第一次,我想知道如果我做对了还是不对。到现在为止,我对加密的想法是这样的:Java加密文件数据并将其写入同一文件

选择一个文件- >阅读它的所有字节,并把它添加到字节数组- >加密的字节数组- >写入同一个文件的加密字节。

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

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

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?!

(NOTE)由于某些原因,我在同一个文件上写了加密数据。我对硬盘的工作原理并不熟悉。我的理由之一是防止以后恢复文件。有什么我必须知道的吗?我在做什么防止未加密的文件以后恢复?


编辑 @erickson指出在他的回答一些重要的东西。我知道这种加密文件的方式并不安全。我正在考虑防止,阻止文件后来被恢复。我的意思是加密文件并将其保存在硬盘中是没有任何意义的,如果你曾经将它加密的话。根据我的经验,每次我恢复一个文件,我都会对其进行最后编辑,并且我永远无法获得更改的历史记录。如果我在第一时间没有错,我认为这一定是一样的。我该如何帮助防止数据恢复呢?

+0

处理您描述的操作的标准方法是创建一个新文件,将处理过的字节写入它,然后删除输入文件。例如,参见'gzip'。在任何现代(日志式)文件系统上,无论如何你都不会重写数据;你根本无法控制。 – chrylis

+0

@chrylis我知道这不是标准的方法。我可以处理在其他目录中写入输出文件。正如我已经指出的那样,我有一些理由以非标准的方式来做到这一点(我确实对它们有怀疑)。像防止文件恢复以后访问普通(未加密)文件和其他... –

+0

了解,但在原地覆盖文件将无法完成,所以这是很多并发症,没有任何好处。 – chrylis

回答

2

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

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

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

+0

嗯,我在想这可能不安全。你是对的。在文件上写入时(例如关闭计算机)任何事故都会破坏一切。 感谢您提供有关覆盖的信息。我在加密时至少能够帮助我保护数据恢复?! 我想知道数据何时可恢复,几乎没有用于加密文件。根据我的经验,每次我恢复一个文件,我都会对其进行最后编辑,并且我永远无法获得更改的历史记录。我以为这一定是一样的.... –

1

读完文件后需要关闭读卡器。你目前正在这样做:

bufferedInputStream.close(); 

所以没关系。 然后,而不是清理文件,你可以只是简单的覆盖它使用:

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

希望帮助:)

+0

谢谢,这应该可能工作。但是这不会将所有三个动作(读取 - 加密 - 写入)同时处理在一起。 (或者它??!)我正在寻找的文件正在加密和阅读文件时写... –

相关问题