2016-11-18 13 views
3

私はサーバーから暗号化された文字列を解読しようとしています。しかし、私はそれを復号化するときに私はフォールバックエラーが発生します。私は文字列を正常に解読する必要があります。私はAES/CBC/NoPaddingを使用するときに我々は暗号悪意解読java

> java.lang.Exception: [decrypt] error:1e06b065:Cipher 
> functions:EVP_DecryptFinal_ex:BAD_DECRYPT 
11-18 12:32:12.976 14325-14325/aes.example.com.aes_encyrption_demo W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err: java.lang.Exception: [decrypt] error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at aes.example.com.aes_encyrption_demo.MCrypt.decrypt(MCrypt.java:73) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at aes.example.com.aes_encyrption_demo.MainActivity.onCreate(MainActivity.java:59) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.Activity.performCreate(Activity.java:6303) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.ActivityThread.access$900(ActivityThread.java:153) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:102) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.os.Looper.loop(Looper.java:148) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:5442) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) 
11-18 12:32:13.069 14325-14325/aes.example.com.aes_encyrption_demo W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) 

AES 256 CBCを使用している、私は解読することができるよが、テキストはジャンク文字が付加さ です。

復号化さ

:2:{S:5: "電子メール"; S:24: "[email protected]"; S:8: "パスワード"; S:7: "Test123 ";}

実際の文字列 :2:{S:5:" 電子メール "; S:24:" [email protected] "; S:8:" パスワード "; S :7: "Test123";}

ケース1:AES/CBC/PKCS5Padding:BAD_DECRYPTまたはBAD PADDINGエラー

ケース2:AES/CBC/NoPadding:復号文の最後にジャンク値は

public class MCrypt { 

    private String iv = "fedcba";//Dummy iv (CHANGE IT!) 
    private IvParameterSpec ivspec; 
    private SecretKeySpec keyspec; 
    private Cipher cipher; 

    private String SecretKey = "abcdef";//Dummy secretKey (CHANGE IT!) 

    public MCrypt() 
    { 
     ivspec = new IvParameterSpec(iv.getBytes()); 

     keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES"); 

     try { 
      cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
//   cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public byte[] encrypt(String text) throws Exception 
    { 
     if(text == null || text.length() == 0) 
      throw new Exception("Empty string"); 

     byte[] encrypted = null; 

     try { 
      cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); 

      encrypted = cipher.doFinal(padString(text).getBytes()); 
     } catch (Exception e) 
     { 
      throw new Exception("[encrypt] " + e.getMessage()); 
     } 

     return encrypted; 
    } 

    public byte[] decrypt(String code) throws Exception 
    { 
     if(code == null || code.length() == 0) 
      throw new Exception("Empty string"); 

     byte[] decrypted = null; 

     try { 
      cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); 

      decrypted = cipher.doFinal(hexToBytes(code)); 
     } catch (Exception e) 
     { 
      throw new Exception("[decrypt] " + e.getMessage()); 
     } 
     return decrypted; 
    } 



    public static String bytesToHex(byte[] data) 
    { 
     if (data==null) 
     { 
      return null; 
     } 

     int len = data.length; 
     String str = ""; 
     for (int i=0; i<len; i++) { 
      if ((data[i]&0xFF)<16) 
       str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF); 
      else 
       str = str + java.lang.Integer.toHexString(data[i]&0xFF); 
     } 
     return str; 
    } 


    public static byte[] hexToBytes(String str) { 
     if (str==null) { 
      return null; 
     } else if (str.length() < 2) { 
      return null; 
     } else { 
      int len = str.length()/2; 
      byte[] buffer = new byte[len]; 
      for (int i=0; i<len; i++) { 
       buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16); 
      } 
      return buffer; 
     } 
    } 



    private static String padString(String source) 
    { 
     char paddingChar = ' '; 
     int size = 16; 
     int x = source.length() % size; 
     int padLength = size - x; 

     for (int i = 0; i < padLength; i++) 
     { 
      source += paddingChar; 
     } 

     return source; 
    } 

Activity.java

try{ 
     decrypted = new String(mcrypt.decrypt(msg)); 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     System.out.println("decrypted: " + decrypted); 

PHP

<?php 

class MCrypt 
{ 
     private $iv = 'fedcba'; #Same as in JAVA 
     private $key = 'abcdef'; #Same as in JAVA 


     function __construct() 
     { 
     } 

     function encrypt($str) { 

      //$key = $this->hex2bin($key);  
      $iv = $this->iv; 

      $td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv); 

      mcrypt_generic_init($td, $this->key, $iv); 
      $encrypted = mcrypt_generic($td, $str); 

      mcrypt_generic_deinit($td); 
      mcrypt_module_close($td); 

      return bin2hex($encrypted); 
     } 

     function decrypt($code) { 
      //$key = $this->hex2bin($key); 
      $code = $this->hex2bin($code); 
      $iv = $this->iv; 

      $td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv); 

      mcrypt_generic_init($td, $this->key, $iv); 
      $decrypted = mdecrypt_generic($td, $code); 

      mcrypt_generic_deinit($td); 
      mcrypt_module_close($td); 

      return utf8_encode(trim($decrypted)); 
     } 

     protected function hex2bin($hexdata) { 
      $bindata = ''; 

      for ($i = 0; $i < strlen($hexdata); $i += 2) { 
       $bindata .= chr(hexdec(substr($hexdata, $i, 2))); 
      } 

      return $bindata; 
     } 

} 

私はすでに試してみましたstackoverflow上の多くのリンク。

参考: http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php.html

私はAES/CBC/PKCS5Paddingを使用した場合、復号はエラーで失敗EDIT

パディングが正しく、サーバーのPHPコードによって適用されていないため、これは、ありますそれとも私の終わりに何か?どのようにこれを解決することができます。

EDIT 2

は、私が16バイトのキーと試みたが、悪いパディング例外を得ていた問題 を発見し、サーバー側のコードは、PKCS7を実装していなかった事実によるものでした。 PKCS7パディングがサーバー側で実装された後、問題は解決されました。 AES/CBC/PKCS5Paddingモードでは、パディングが暗号化された文字列に追加されないと、不正なパディング例外が発生します。

+0

平文の末尾に、次のブロック境界までtを拡張するための埋め込みが追加されています。 AESはブロック暗号です。最後のこれらのジャンク文字は[パディング](https://en.wikipedia.org/wiki/Padding_(暗号化))です。それらを見て、どのタイプのパディングが使用されているかを見て、そのパディングのタイプを期待する解読方法を設定します。他のエラーについては、エラーメッセージがあなたに伝えていることを見てください。 – rossum

+0

@Robert私は迷惑メールの値を取得しません、正しいテキストの後に迷惑メールの値があります –

+0

AES/CBC/PKCS5Paddingを使用すると復号化がエラーで失敗するのはサーバーのPHPによって正しく埋められていないためですコード、またはそれは私の最後に何か? –

答えて

0

は、私はまた、16バイトのキーと試みた問題を発見しました。私はBad Paddingの例外を受け取りました。それは、サーバー側のコードがPKCS7を実装していなかったからです。

AES/CBC/NoPaddingモードを使用していたときにエラーは発生しませんでしたが、復号化された文字列の最後にはジャンク値が含まれていました。これは、パディングが暗号化された文字列に追加されなかったためです。

PKCS7パディングがサーバー側で実装された後、問題は解決されました。 AES/CBC/PKCS5Paddingモードでは、パディングが暗号化された文字列に追加されないと、不正なパディング例外が発生します。

暗号化中にPHPで埋め込みを実装する場合は、https://gist.github.com/Halama/5956871を参照してください。

+0

そして、あなたが達成しようとしたどのレベルの機密性も壊す可能性のあるパディング・オラクル攻撃に対して完全に脆弱です。おとぎ話のセキュリティを信じない限り、TLSを使用してください。上記のソリューションは**動作しますが、安全ではありません**。 –

+0

@MaartenBodewesありがとうTLSを勉強し、それを使用しようとします。私はまだ学んでいる暗号化/解読には新しいです。 –

2

PHPは、非決定的なゼロパディングを使用します。このパディングは、復号化されたバイト配列からゼロの値を持つバイトをすべて削除するだけで削除できます。もちろん、平文から0バイトの値も削除されます。


注:

  • は、AES-256はあなたのキーサイズをときが256ビットで使用されています。現在は128ビットで構成されているため、AES-128が使用される可能性があります。
  • あなたは現在、Javaで文字列と PHPの文字列のエンコーディングのいくつかの種類のためのプラットフォームのエンコーディングを使用している、あなたはエンコードの一致が(明示的にエンコーディングを指定せずにnew String(byte[])またはgetBytes()を使用しない)ことを確認する必要があります。
  • キーは文字ではなくランダムなバイトで構成されます。
  • トランスポートモードの暗号化にCBCを使用しないでください。

のUSE SSL/TLS INSTEAD

+0

http://stackoverflow.com/questions/13467343/want-to-use-aes-256-cbc-with-32-bytes-but-it-shows-java-security-invalidalgorithこれは私が試したときに起こることです128ビットの鍵を使用してください –

関連する問題