2017-11-27 4 views
0

私は暗号化されており、このようなファイルに書き込まれているいくつかのアカウント情報があります。暗号化されたテキストをファイルから読み込み、復号化するにはどうすればよいですか?

//imports here 
public class Main 

    public static void main(String[] args) { 


     try { 
      String text = "this text will be encrypted"; 

      String key = "Bar12345Bar12345"; 

      //Create key and cipher 
      Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 

      //encrypt text 
      cipher.init(Cipher.ENCRYPT_MODE, aesKey); 
      byte[] encrypted = cipher.doFinal(text.getBytes()); 
      write(new String(encrypted)); 

     } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { 
      e.printStackTrace(); 
     } 

    } 

    public static void write(String message) { 
     BufferedWriter bw = null; 
     FileWriter fw = null; 

     try { 

      String data = message; 

      File file = new File(FILENAME); 
      if (!file.exists()) { 
       file.createNewFile(); 
      } 


      fw = new FileWriter(file.getAbsoluteFile(), true); 
      bw = new BufferedWriter(fw); 

      bw.write(data); 

     } catch (IOException e) { 

      e.printStackTrace(); 

     } finally { 

      try { 

       if (bw != null) 
        bw.close(); 

       if (fw != null) 
        fw.close(); 

      } catch (IOException ex) { 

       ex.printStackTrace(); 

      } 
     } 
    } 

} 

ので、ファイルの内容は、その間の任意の中断することなく、1つの文字列です。

String key = "Bar12345Bar12345"; 
Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
Cipher cipher = Cipher.getInstance("AES"); 
byte[] encrypted = text.getBytes(); 
cipher.init(Cipher.DECRYPT_MODE, aesKey); 
String decrypted = new String(cipher.doFinal(encrypted)); 
System.err.println(decrypted); 

これは限りbyte[] encryptedは、暗号化処理のように使用したのと同じであると正常に動作しますが、私は、ファイルから暗号化されたテキストを読みしようとすると:私は、文字列の暗号化を解除したい場合は、私はこれを行うだろうFileReaderのとBufferedReaderを使用して、あなたが任意の復号化を実行しようとする前に、それは

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher 
+0

これは、リソースを自分で閉じるのではなく、2017、try ** with try-with-resources **です。 –

答えて

1

はlines.getByte()からの暗号文と暗号化処理からの暗号文を比較例外をスローlines.getByte()を使用してバイトにそれを変更します。彼らはおそらく異なっているでしょう。解読する前にファイル全体を最初にbyte []に​​読み込んでみてください。対称暗号は、同じサイズ(この場合は16バイト)のブロックで作業する必要があります。

貧弱なプロトコルの選択肢について私がコメントしていない場合は、私も黙っています。

  1. ハードコーディングされたキー - アプリケーションで暗号化キーをハードコードすることは絶対にしないでください。暗号化キーを変更する必要がある場合は、これを行うことはできません。アプリケーションがエンドユーザーに配布されている場合は、の文字列などのアプリケーションを使用してキーを簡単に復元できます。
  2. あなたの操作モードにはECBが使用されています。 ECBには、ブロックシャッフルなどの攻撃を受ける方法がいくつかあります。ブロックシャッフルは、攻撃者が暗号鍵を持たずにデータを復号することを可能にします。

自分で暗号化するのは難しいです。あなたの問題を別の方法で解決することを検討してください。

+0

私は、バイト[]を直接書き込んだり、読み込んだり、書き込んだり読んだりする前に文字列に変換する代わりに、この問題を解決しました。 1.これはサーバーサイドのアプリケーションなので、問題はありませんが、どのように2を解決するのですか? –

+0

1.まだ問題があります。開発者があなたのチームを悪い条件にしてしまったり、サーバーが誤って構成されたり、アプリケーションやサーバーの別のアプリケーションのバグによってファイルシステムへの読み取りアクセスが許可された場合、キーが侵害されます。これを修正する最も簡単な方法は、何らかの設定ファイルに暗号化キーを設定することです。 2. CBC、CTRなどの異なる動作モードを使用することで修正できますが、依然として適切なプロトコルに従う必要があります。 (IVを適切に選択するなど)暗号化は非常に困難です。あなたが使うことのできるすぐれたソリューションがないと確信していますか? – user52472

+0

私はCBCモードに切り替えましたが、どうすればこのような設定ファイルを使用できますか?私はLinux上にいる –

1

encrypted配列の内容を(プラットフォームエンコードされた)テキストとして扱いますが、そうではありません。ランダムなバイトで構成されています。

encryptedの内容を直接書き込んでバイナリファイルを作成する必要があります。それとも、最初にencryptedをbase64にエンコードしてテキストファイルを作成できます。

現在、行を読み込もうとしていますが、行はありません。そしてそこにいくつかの行末がある場合、それらのバイトが解読される前に暗号文から取り除かれます。

new String(encrypted)を実行すると、サポートされていないエンコードが警告なしで文字列から削除されるため、データの一部が失われる可能性もあります。


単語「暗号文」は少し誤解を招くことに注意してください。 AESのような現代の暗号は、テキストではなくバイナリデータを扱います。

関連する問題