2016-05-04 14 views
2

私はこのコードを使用して暗号化されている自分のコンピュータ上のファイルをしました:JavaでMD5とDESを使用して「与えられた最終ブロックに適切に埋め込まれていない」デバッグ方法

//Arbitrarily selected 8-byte salt sequence: 
private static final byte[] salt = { 
    (byte) 0x43, (byte) 0x76, (byte) 0x95, (byte) 0xc7, 
    (byte) 0x5b, (byte) 0xd7, (byte) 0x45, (byte) 0x17 
}; 

public static Cipher makeCipher(String pass, Boolean decryptMode) throws GeneralSecurityException{ 

    //Use a KeyFactory to derive the corresponding key from the passphrase: 
    PBEKeySpec keySpec = new PBEKeySpec(pass.toCharArray()); 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");//PBKDF2WithHmacSHA256 
    SecretKey key = keyFactory.generateSecret(keySpec); 

    //Create parameters from the salt and an arbitrary number of iterations: 
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 42); 

    //Set up the cipher: 
    Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); 

    //Set the cipher mode to decryption or encryption: 
    if(decryptMode){ 
     cipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec); 
    } else { 
     cipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec); 
    } 

    return cipher; 
} 


/**Encrypts one file to a second file using a key derived from a passphrase:**/ 
public static void encryptFile(String fileName, String pass){ 
    try{ 
     byte[] decData; 
     byte[] encData; 
     File inFile = new File(fileName); 
     //Generate the cipher using pass: 
     Cipher cipher = Main.makeCipher(pass, true); 

     //Read in the file: 
     FileInputStream inStream = new FileInputStream(inFile); 

     int blockSize = 8; 
     //Figure out how many bytes are padded 
     int paddedCount = blockSize - ((int)inFile.length() % blockSize); 

     //Figure out full size including padding 
     int padded = (int)inFile.length() + paddedCount; 

     decData = new byte[padded]; 


     inStream.read(decData); 

     inStream.close(); 

     //Write out padding bytes as per PKCS5 algorithm 
     for(int i = (int)inFile.length(); i < padded; ++i) { 
      decData[i] = (byte)paddedCount; 
     } 

     //Encrypt the file data: 
     encData = cipher.doFinal(decData); 

     writeToFile(fileName, encData); 

    } catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

private static void writeToFile(String path, byte[] data) { 
    try { 
     File file = new File(path); 

     //Write the encrypted data to a new file: 
     FileOutputStream outStream = new FileOutputStream(file); 
     outStream.write(data); 
     outStream.close(); 
    } catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

ファイルを暗号化するために使用されるキーがある:「テスト」、「テスト」または「暴力団員」。

問題は、暗号化されたファイルにアクセスできないという事実にあります。

/**Decrypts one file to a second file using a key derived from a passphrase:**/ 
public static void decryptFile(String fileName, String pass, String addition) 
         throws GeneralSecurityException, IOException{ 
    byte[] encData; 
    byte[] decData; 
    File inFile = new File(fileName); 

    //Generate the cipher using pass: 
    Cipher cipher = Main.makeCipher(pass, false); 

    //Read in the file: 
    FileInputStream inStream = new FileInputStream(inFile); 
    encData = new byte[(int)inFile.length()]; 
    inStream.read(encData); 
    inStream.close(); 

    //Decrypt the file data: 
    decData = cipher.doFinal(encData); 

    //Write the decrypted data to a new file: 
    FileOutputStream target = new FileOutputStream(new File(fileName + addition+ ".png")); 
    target.write(decData); 
    target.close(); 
} 

しかし、ファイルの暗号化を解除しようとすると、次のエラーがスローされます:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded 
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966) 
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824) 
at com.sun.crypto.provider.PBES1Core.doFinal(PBES1Core.java:416) 
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(PBEWithMD5AndDESCipher.java:316) 
at javax.crypto.Cipher.doFinal(Cipher.java:2165) 
at Main.decryptFile(Main.java:145) 
at Main.main(Main.java:22) 

この行です:

decData = cipher.doFinal(encData); 

この私が動作するはず復号化方法を持っています多くのファイルの1つにすぎません。私のプログラミングプロジェクト、ウェブサイト、仕事、インターンシップ関連のファイルはすべて暗号化されています。

誰かが私のファイルへのアクセスを回復するのを助けることができたら本当に感謝します。ファイルが暗号化された理由は、テスト後に私が変更しなかった私のユーザフォルダのいくつかの不正なアクセス権設定のためです。これは現在修正されています。

私はデータを正しく暗号化しなかった可能性がありますので、復号化できませんか?

暗号化された単語文書をアップロードしたので、問題の内容を把握することができます。ここで見つけることができます:

http://www70.zippyshare.com/v/KfY6qFGD/file.html

このドキュメントは、HTML/CSS関連のチェックの3つのリストが含まれています。..

+0

要約すると、これらのファイルを誤って暗号化しましたか?解読しようとしている場合は、最初にバックアップを確認することをお勧めします - あなたを助けることができるものはありますか?そうでない場合は、少なくともパスフレーズとコードを試してみると、すべてが失われていない可能性があります。ただし、解読し続ける必要がある場合は、まずバックアップを取る** - 事態を悪化させるようなことがあるかもしれないので、予防策を講じてください。 – halfer

+0

こんにちは、はいこの問題の原因となった間違ったフォルダでプロジェクトを実行しました。悲しいことに、私はバックアップを作っていない。私は同意する、私は今それを作っている。あなたのお返事ありがとうございました! – KasFeenema

+0

[この可能な重複](https://stackoverflow.com/questions/8049872/given-final-block-not-properly-padded)または[数百の可能なdups](https://stackoverflow.com/)を参照してください。検索?q =与えられた+ final +ブロック+ not +適切に+ padded + Java)。 – halfer

答えて

1

この例外メッセージは、キーが間違っていることを意味します。

まず、暗号化されたデータはDESを使用して復号化されます。

キーが間違っていると、結果のデータはランダムになります。 1/2560x01で終わり、正しいPKCSパディングであり、確率1/(256 * 256)0x02 0x02で終わり、正しいパディングであり、確率1/(256 * 256 * 256)となります。また、正しいパディングなどである0x03 0x03 0x03で終了します。これらの非常に起こりそうなケースでは例外はスローされませんが、復号化されたデータは間違いです。


上記OPのコード内の1つの重要なバグがあります:doFinal(...)は同様にパディングを追加します。それはする必要はありませんがencryptFile方法は、入力されたパディングを行います。そのため、パディングが2回追加され、復号後に結果のデータに1つのパディングが残ります。

関連する問題