2011-12-26 13 views
-1

JavaのJCAとJCEを使用して、テキストのチャンクを暗号化および復号化するための簡単なアプリケーションを作成しようとしています。 JCAとJCEを使ったJavaのテキストチャンクの暗号化と復号化

は、これまでのところ、暗号化部は動作しますが、復号化の際、それは私に次の例外を与える:

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

これは私は2つの暗号、encCipher、およびdecCipherを初期化する部分です。

PBEKeySpec pbeKeySpec; 
PBEParameterSpec paramSpec; 
SecretKeyFactory keyFac; 
byte[] salt = {(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, 
       (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99}; 
int count = 20; 
paramSpec = new PBEParameterSpec(salt, count); 

try { 
    pbeKeySpec = new PBEKeySpec("my_password".toCharArray(), salt, count); 
    SecretKey secretKey = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(pbeKeySpec); 

    encCipher = Cipher.getInstance(secretKey.getAlgorithm()); 
    encCipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); 
    decCipher = Cipher.getInstance(secretKey.getAlgorithm()); 
    decCipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); 

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

私は、Java暗号化アーキテクチャを使用しての経験を持っていない、私は、エラーを修正することができるか知りたいのです。

例外はloadClientsのdecCipher.doFinalの行で発生します。

private void saveClients() { 
    String plainText = ""; 
    String encText = ""; 
    Set<String> clients = my_clients.keySet(); 
     try { 
      PrintWriter out = new PrintWriter(new File(output_file)); 
      for (String client : clients) { 
       long client_time = my_clients.get(client); 
       plainText = client + " " + client_time; 

       encText = new String(encCipher.doFinal(plainText.getBytes())); 
       out.println(encText); 
      } 
      out.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void loadClients() { 
     BufferedReader in; 
     String line; 
     try { 
      in = new BufferedReader(new FileReader(output_file)); 
      while ((line = in.readLine()) != null) { 
       byte[] decBytes = decCipher.doFinal(line.getBytes()); 
       String decText = new String(decBytes); 
       String[] client_data = decText.split("[ ]"); 
       my_clients.put(client_data[0], Long.parseLong(client_data[1])); 
      } 
      in.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
+0

エラーは、暗号化と復号化に使用されたコードにあります。このコードを表示してください。私はあなたのコードを次のように試して、期待どおりに動作します:byte [] text = "Hello world" .getBytes( "UTF-8"); byte [] encrypted = encCipher.doFinal(text); byte [] decrypted = decCipher.doFinal(暗号化);System.out.println(新しい文字列(暗号化された "UTF-8")); –

+0

暗号化と復号化に使用する関数を追加しました。読み込みにBufferedReaderを使用し、OutputStreamではなくファイルを書き込むためにPrintWriterを使用するため、エラーが発生する可能性がありますか? – user852689

答えて

1

問題は、バイトを文字列に変換するという事実に起因します。デフォルトのプラットフォームエンコーディングがASCIIであるとします。これは、暗号化されたテキストに含まれるバイトの半分(128バイト以上)が有効な文字を表していないことを意味します。さらに、暗号化されたテキストごとに1行ずつ記述します。したがって、暗号化されたバイト配列に改行文字が含まれていると、実際には2行をライターに書き込んで、各行を1つずつ解読しようとしますが、例外が発生します。

暗号化されたデータを格納および転送するためにバイトを使用するか、Base64のような非ロッシーなアルゴリズムを使用して文字列に変換してください(すべてが印刷可能な文字に変換されます)。 Apache commons-codecにはBase64実装があります。