2017-06-19 11 views
0

javaでファイルを復号しようとしています。解読されたファイルの最初の16バイトはIV(初期化ベクトル)です。上記の例外を解決する際にお手伝いください。javax.crypto.BadPaddingException:解読中に最終ブロックが適切に埋められない場合

私はIVをAESFileEncryption()の出力ファイルに追加してから解読中にそれを読み取ろうとしています。

ありがとうございます。

public class AESFileEncryption { 
public static void encrypt(String path,String pwd) throws Exception { 

    FileOutputStream outFile; 

    try ( 
      FileInputStream inFile = new FileInputStream(path)) { 

     String fileName=path; 

     System.out.println(path); 

     outFile = new FileOutputStream(fileName+".aes"); 
     // password to encrypt the file 
     String password = pwd; 
     byte[] salt = { 
     (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, 
     (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 
     }; 

     SecretKeyFactory factory = SecretKeyFactory 
       .getInstance("PBKDF2WithHmacSHA1"); 
     KeySpec keySpec = new PBEKeySpec(password.toCharArray(),salt,65536,128);// user-chosen password that can be used with password-based encryption (PBE). 
     SecretKey secretKey = factory.generateSecret(keySpec); 
     SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");//Secret KeySpec is a class and implements inteface SecretKey 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     SecureRandom random = new SecureRandom(); 
     byte bytes[] = new byte[16]; 
     random.nextBytes(bytes); 
    IvParameterSpec ivspec = new IvParameterSpec(bytes); 
     cipher.init(Cipher.ENCRYPT_MODE, secret,ivspec);//opmode,key 
     outFile.write(bytes); 
     byte[] input = new byte[64]; 
     int bytesRead; 
     while ((bytesRead = inFile.read(input)) != -1) { 
      byte[] output = cipher.update(input, 0, bytesRead); 
      if (output != null) 
       Files.write(Paths.get(fileName+".aes"), output, StandardOpenOption.APPEND); 

     } byte[] output = cipher.doFinal(); 
     if (output != null) 
      Files.write(Paths.get(fileName+".aes"), output, StandardOpenOption.APPEND); 
    } 
    outFile.flush(); 
    outFile.close(); 
    File f=new File(path); 
    boolean x=f.delete(); 
    if(x){ 
     System.out.println("File deleted"); 
    } 
    JOptionPane.showMessageDialog(null,"File Encrypted."); 

} 
} 

復号化コード

public class AESFileDecryption { 
public static void decrypt(String path,String pwd) throws Exception { 

    String password = pwd; 
    String fileName=path; 
    File file=new File(path); 
     //System.out.println(inFile.toString()); 
     String fileNameWithOutExt = path.replaceFirst("[.][^.]+$", ""); 
     System.out.println(fileName); 
     System.out.println(fileNameWithOutExt); 
     byte[] salt = { 
     (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, 
     (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 
    }; 
    System.out.println("1"); 
    FileInputStream fis = new FileInputStream(path); 
    SecretKeyFactory factory = SecretKeyFactory 
      .getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec keySpec = new PBEKeySpec(password.toCharArray(),salt,65536,128); 
    SecretKey tmp = factory.generateSecret(keySpec); 
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
    System.out.println("2"); 
    // file decryption 
    Cipher cipher=null; 
    byte bytes[]=new byte[16]; 
    fis.read(bytes, 0, 16); 
    IvParameterSpec ivspec = new IvParameterSpec(bytes); 

    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.DECRYPT_MODE, secret, ivspec); 
    System.out.println("3"); 
    FileOutputStream fos = new FileOutputStream(fileNameWithOutExt); 
    System.out.println("4"); 
    byte[] in = new byte[64]; 
    int read; 
    while ((read = fis.read(in,16,(int)file.length()-16)) != -1) { 
     byte[] output = cipher.update(in, 0, read); 
     if (output != null) 
      fos.write(output); 
    } 
    try{ 
    byte[] output = cipher.doFinal(); 
    if (output != null) 
     fos.write(output); 
    fis.close(); 
    fos.flush(); 
    fos.close(); 
    System.out.println("File Decrypted."); 
} 
catch(IOException | BadPaddingException | IllegalBlockSizeException e) 
{ 
    System.out.println(e+""); 
} 
} 
} 

答えて

5

小さな例でいくつかの問題が、ほとんどすぐにあなたの問題はあなたが混乱しているようだ

while ((read = fis.read(in,16,(int)file.length()-16)) != -1) { 

ラインがあるものがあります。 read()へのoffsetパラメータの意味についてです。これはファイルへのオフセットではなく、最初のパラメータで指定された配列へのオフセット(in)です。

私が見る他の問題の非網羅的なリストは、次のとおりです。

  • は、2つの独立したメカニズム(FileOutputStream.write()Files.write())を使用してファイルに書き込みます。これは実際にあなたのプログラムを実行したときに大丈夫でしたが、問題を求めているようです。ここにFiles.write()を使用する理由はありません。
  • fis.read(bytes, 0, 16);戻り値はチェックされません。

あなたは、あなたが快適であるいくつかのIOイディオムを見つけるのに苦労しているようです。あるいは実験しているだけかもしれません。あなたにジャグリングのオプションを与えるリスクがある場合、GoogleのオープンソースGuavaライブラリの調査を検討することもできます。多くの人々は、必要なものだけを持っていることを知ります。

+1

正しく覚えていれば、ファイルハンドルは現在のスレッドにロックされています。だから私はそれが(2つの異なる方法を使用してファイルを書く)はうまくいったことに驚くことはありませんが、**まだ問題を求めています** –

+0

私はそれを得ました。ありがとう。 IVのファイルの最初の16バイトを読み込んだ後、残りのバイトを解読する方法を教えてください。 –

関連する問題