2012-10-18 91 views
1

我有一個程序必須加密音頻文件,然後解密它,如果需要。我測試了一些其他類型的文件,如.bin或.txt。我得到的問題是,解密文件在實際內容之前有一些奇怪的字符,例如源文件包含「010101」,並且在加密之後,解密文件具有「¬íw0w010101」。破解Java解密文件

我的加密方法的代碼放在這裏:

public void cipherTheAudioFile(String fileDir, String fileToCipher) throws   FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException { 
    File audioSourceFile = new File(fileDir + "\\" + fileToCipher); 
    ObjectOutputStream oos = new ObjectOutputStream(
     new CipherOutputStream(new FileOutputStream(
      new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToCipher + ".sky"), cipher)); 

    byte[] audioFileInBytes = FileUtils.readFileToByteArray(audioSourceFile); 
    oos.write(audioFileInBytes); 

    fos = new FileOutputStream(KEY_FILE); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance(ENCRYPTION_ALGORITHM); 
    DESKeySpec keyspec = (DESKeySpec) skf.getKeySpec(key, DESKeySpec.class); 
    fos.write(keyspec.getKey()); 

    fos.close(); 
    oos.close(); 
} 

我的解密方法的代碼放在這裏:

public void decryptTheAudioFile(String fileDir, String fileToDecipher) throws NoSuchAlgorithmException, NoSuchPaddingException, FileNotFoundException, IOException, ClassNotFoundException, InvalidKeySpecException, InvalidKeyException { 
    fis = new FileInputStream(keyFile); 
    byte[] keyspecbytes = new byte[fis.available()]; 

    File fileToWriteIn = createFileToWriteIn(fileDir, fileToDecipher); 

    fis.read(keyspecbytes); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance(encryptionAlgorithm); 
    DESKeySpec keyspec = new DESKeySpec(keyspecbytes); 
    SecretKey key = skf.generateSecret(keyspec); 
    Cipher cipher = Cipher.getInstance(encryptionAlgorithm); 
    cipher.init(Cipher.DECRYPT_MODE, key); 

    ObjectInputStream ois = new ObjectInputStream(
     new CipherInputStream(
      new FileInputStream(new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToDecipher + ".sky"), cipher)); 
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileToWriteIn)); 

    byte[] audioFileInBytes = new byte[1024]; 

    int numRead = 0; 
    while ((numRead = ois.read(audioFileInBytes)) >= 0) { 
     oos.write(audioFileInBytes, 0, numRead); 
    } 

    oos.close(); 
    fis.close(); 
    ois.close(); 
} 

附:這可能與編碼有關,但我不確定。

編輯

好吧,我已經改爲FileWriters,但仍然沒有改變。代碼如下:

OutputStream os = new FileOutputStream(new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToCipher + ".sky"); 
    CipherInputStream cis = new CipherInputStream(new FileInputStream(audioSourceFile), cipher); 
    byte[] audioFileInBytes = new byte[1024]; 
    int numRead = 0; 
    while ((numRead = cis.read(audioFileInBytes)) >= 0) { 
      os.write(audioFileInBytes, 0, numRead); 
    } 

同樣的解密器。

+0

如果您懷疑編碼可能是原因,那麼在文本文件的情況下,輸入文件可能是帶有BOM的UTF-8和不帶BOM的輸出UTF-8。 Wiki(http://en.wikipedia.org/wiki/UTF-8):許多Windows程序(包括Windows記事本)在保存爲UTF-8的任何文檔的開始處添加字節0xEF,0xBB,0xBF。 – Indrek

+0

是的,我測試了.txt文件,但我的實際任務是針對.mp3當我解密.mp3文件時,我收到的東西聽起來更像是dubstep,但不是實際的音頻文件。 :) – user

+1

有些人喜歡dubstep。對他們來說,這可能是一個有效的加密/解密鏈。 :P – brimborium

回答

2

問題在於decryptTheAudioFile方法寫入文件的方式。具體而言,問題在於它使用的是ObjectOutputStream。這是添加一個對象序列化標題。但它根本不屬於那裏。

的解決辦法是,從decryptTheAudioFile擺脫這樣的:

ObjectOutputStream oos = new ObjectOutputStream(
     new FileOutputStream(fileToWriteIn)); 

,並用此替代它:

OutputStream os = new FileOutputStream(fileToWriteIn); 

,並更改代碼的其餘部分寫os。您的代碼需要反映您如何閱讀cipherTheAudioFile中的文件。


這將是一個好主意,擺脫對方ObjectStream實例太多,簡單的讀寫爲純Streams。其他ObjectStream是無害的(主要),但他們實際上沒有實現任何東西。

+0

謝謝你的回答!剛剛嘗試過,但仍然得到相同的東西。 :( – user

+0

你是否像我說過的那樣改變了最後一個?因爲那是真正的問題所在 –

+0

好吧,我做了。它全部從CipherInputStream(它處理指向的文件)讀取並寫入os。在加密器中,我從源文件中讀取並寫入加密的文件;在解密器中,我從加密中讀取並寫入新文件。 – user

0

刪除所有的ObjectOutputStreams和ObjectInputStreams。你正在寫一個字節數組,所以它們是不必要的。您看到的額外字節可能會告訴您字節[]的類型和大小。

+0

你是說我應該使用簡單的I/O流,但不是對象? – user

+0

當你寫一個字節[]以外的東西時,你可能需要它們,但不在這裏。 –