2016-01-11 71 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

謝謝,這應該可能工作。但是這不會將所有三個動作(讀取 - 加密 - 寫入)同時處理在一起。 (或者它??!)我正在尋找的文件正在加密和閱讀文件時寫... –

相關問題