2012-10-18 50 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

当你写一个字节[]以外的东西时,你可能需要它们,但不在这里。 –