2016-01-21 62 views
8

は、Android/Javaアプリケーション暗号化と復号化

public static void setKey(String myKey) { 

     MessageDigest sha = null; 
     try { 
      key = new byte[]{(byte) '5', (byte) 'F', (byte) '8', (byte) 'p', (byte) 'J', (byte) 't', (byte) 'v', (byte) 'U', (byte) 'm', (byte) 'q', (byte) 'k', (byte) '7', (byte) 'A', (byte) 'M', (byte) 'v', (byte) 'b', (byte) 'q', (byte) 'o', (byte) 'H', (byte) 'M', (byte) '9', (byte) 'a', (byte) 'p', (byte) '4', (byte) '9', (byte) 'm', (byte) 'c', (byte) 'u', (byte) 'u', (byte) '5', (byte) 'B', (byte) 'X'}; 
      System.out.println(new String(key, "UTF-8")); 
      secretKey = new SecretKeySpec(key, "AES"); 
     } catch (UnsupportedEncodingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 


    public static String encrypt(String strToEncrypt) { 
     try { 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
      setEncryptedarr(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))); 
      setEncryptedString(String.valueOf(Base64.encode(cipher.doFinal(strToEncrypt.getBytes("UTF-8")), Base64.DEFAULT))); 
      //setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8")))); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.out.println("Error while encrypting: " + e.toString()); 
     } 
     return null; 
    } 

    public static String decryptbyte(byte[] strToDecrypt) { 
     try { 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); 
      cipher.init(Cipher.DECRYPT_MODE, secretKey); 
      setDecryptedarr(cipher.doFinal(strToDecrypt)); 
      System.out.println("encrypt : decropted size : " + getDecryptedarr().length); 
      setDecryptedString(new String(cipher.doFinal(strToDecrypt))); 
     } catch (Exception e) { 
      System.out.println("Error wnhile decrypting: " + e.toString()); 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    public static String decrypt(String strToDecrypt) { 
     try { 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); 
      cipher.init(Cipher.DECRYPT_MODE, secretKey); 
      setDecryptedarr(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT))); 
      setDecryptedString(new String(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT)))); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      System.out.println("Error while decrypting: " + e.toString()); 

     } 
     return null; 
    } 

では、私は、このコードに取り組んでいます:場合にはそれを使用する場合http://aesencryption.net/私はこのコードを切り取ら使用 がうまく機能していますの: encryptbyteとdecryptbyte whitch []バイトを取ると、私はこのサイトhttp://aesencryption.net/

で暗号化のそれの結果をテストするが、私はそれがデータをdecriptする必要が(応答は文字列が来ている)サーバーから来ました私はバイトを文字列に変換するときはと[]は常にコードthraw例外: javax.crypto.IllegalBlockSizeException:エラー:0606506D:デジタルエンベロープ・ルーチン:EVP_DecryptFinal_ex:間違った最後のブロック長**

私はそれは時に秘密だと思いますStringをbyte []に​​変換します。変換するのが正しい場合は、それを変更します。 アドバイスをお願いします。

このコードthraw例外:末尾==文字に気づく、strToDecrypt = "tATTXSdXI4w0oiu/fzgpyA==" base64エンコーディングを持っていると思われる:

try { 
    AES.setKey(""); 
    final String strToDecrypt = "tATTXSdXI4w0oiu/fzgpyA=="; 
    AES.decryptbyte(toBytes(strToDecrypt.toCharArray())); 
} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

これは、コードの最後のビットは例外

01-21 15:24:55.861 15700-15700/ W/System.err: javax.crypto.IllegalBlockSizeException: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length 
01-21 15:24:55.861 15700-15700/ W/System.err:  at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at javax.crypto.Cipher.doFinal(Cipher.java:1340) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2648) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.ActivityThread.access$900(ActivityThread.java:177) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:102) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.os.Looper.loop(Looper.java:135) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:5910) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at java.lang.reflect.Method.invoke(Method.java:372) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
01-21 15:24:55.861 15700-15700/ W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 
+0

データはどこですか?いくつかの16進ダンプを追加し、それらを調べます。さまざまなエンコーディングを理解すると役に立ちます。また、ECBモードは鍵の文字列のように安全ではありません。これは、暗号化の使用を言いたいのにセキュリティを本当に必要としない場合にのみ適切です。 – zaph

答えて

-1

が、私はそれを解決する....アウトパディングとZeroBytePaddingモードで サーバーの暗号化AESのみ働くモード... が働いているコード:

public class AESCryptt { 
    private static final String TAG = "AESCrypt"; 
    private static final String AES_MODE = "AES/ECB/ZeroBytePadding"; 
    private static final String CHARSET = "UTF-8";// 
    public static boolean DEBUG_LOG_ENABLED = false; 


    private static SecretKeySpec generateKey(final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
     byte[] key = new byte[]{your key in byte here (byte) a, (byte) f , ..... }; 
     SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); 
     return secretKeySpec; 
    } 


    /** 
    * Encrypt and encode message using 256-bit AES with key generated from password. 
    * 
    * 
    * @param password used to generated key 
    * @param message the thing you want to encrypt assumed String UTF-8 
    * @return Base64 encoded CipherText 
    * @throws GeneralSecurityException if problems occur during encryption 
    */ 
    public static String encrypt(final String password, String message) 
      throws GeneralSecurityException { 
     try { 
      final SecretKeySpec key = generateKey(password); 
      log("message", message); 
      byte[] cipherText = encrypt(key, ivBytes, message.getBytes(CHARSET)); 
      //NO_WRAP is important as was getting \n at the end 
      String encoded = String.valueOf(Base64.encodeToString(cipherText, Base64.NO_PADDING)); 
      log("Base64.NO_WRAP", encoded); 
      return encoded; 
     } catch (UnsupportedEncodingException e) { 
      if (DEBUG_LOG_ENABLED) 
       Log.e(TAG, "UnsupportedEncodingException ", e); 
      throw new GeneralSecurityException(e); 
     } 
    } 


    /** 
    * More flexible AES encrypt that doesn't encode 
    * @param key AES key typically 128, 192 or 256 bit 
    * @param iv Initiation Vector 
    * @param message in bytes (assumed it's already been decoded) 
    * @return Encrypted cipher text (not encoded) 
    * @throws GeneralSecurityException if something goes wrong during encryption 
    */ 
    public static byte[] encrypt(final SecretKeySpec key, final byte[] iv, final byte[] message) 
      throws GeneralSecurityException { 
     final Cipher cipher = Cipher.getInstance(AES_MODE); 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     cipher.init(Cipher.ENCRYPT_MODE, key);//, ivSpec 
     byte[] cipherText = cipher.doFinal(message); 
     log("cipherText", cipherText); 
     return cipherText; 
    } 


    /** 
    * Decrypt and decode ciphertext using 256-bit AES with key generated from password 
    * 
    * @param password used to generated key 
    * @param base64EncodedCipherText the encrpyted message encoded with base64 
    * @return message in Plain text (String UTF-8) 
    * @throws GeneralSecurityException if there's an issue decrypting 
    */ 
    public static String decrypt(final String password, String base64EncodedCipherText) 
      throws GeneralSecurityException { 

     try { 
      final SecretKeySpec key = generateKey(password); 
      log("base64EncodedCipherText", base64EncodedCipherText); 
      byte[] decodedCipherText = Base64.decode(base64EncodedCipherText, Base64.DEFAULT); 
      log("decodedCipherText", decodedCipherText); 
      byte[] decryptedBytes = decrypt(key, ivBytes, decodedCipherText); 
      log("decryptedBytes", decryptedBytes); 
      String message = new String(decryptedBytes, CHARSET); 
      log("message", message); 
      return message; 
     } catch (UnsupportedEncodingException e) { 
      if (DEBUG_LOG_ENABLED) 
       Log.e(TAG, "UnsupportedEncodingException ", e); 
      throw new GeneralSecurityException(e); 
     } 
    } 


    /** 
    * More flexible AES decrypt that doesn't encode 
    * 
    * @param key AES key typically 128, 192 or 256 bit 
    * @param iv Initiation Vector 
    * @param decodedCipherText in bytes (assumed it's already been decoded) 
    * @return Decrypted message cipher text (not encoded) 
    * @throws GeneralSecurityException if something goes wrong during encryption 
    */ 
    public static byte[] decrypt(final SecretKeySpec key, final byte[] iv, final byte[] decodedCipherText) 
      throws GeneralSecurityException { 
     final Cipher cipher = Cipher.getInstance(AES_MODE); 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     cipher.init(Cipher.DECRYPT_MODE, key);//, ivSpec 
     byte[] decryptedBytes = cipher.doFinal(decodedCipherText); 
     log("decryptedBytes", decryptedBytes); 
     return decryptedBytes; 
    } 




    private static void log(String what, byte[] bytes) { 
     if (DEBUG_LOG_ENABLED) 
      Log.d(TAG, what + "[" + bytes.length + "] [" + bytesToHex(bytes) + "]"); 
    } 

    private static void log(String what, String value) { 
     if (DEBUG_LOG_ENABLED) 
      Log.d(TAG, what + "[" + value.length() + "] [" + value + "]"); 
    } 


    /** 
    * Converts byte array to hexidecimal useful for logging and fault finding 
    * @param bytes 
    * @return 
    */ 
    private static String bytesToHex(byte[] bytes) { 
     final char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8', 
       '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 
     char[] hexChars = new char[bytes.length * 2]; 
     int v; 
     for (int j = 0; j < bytes.length; j++) { 
      v = bytes[j] & 0xFF; 
      hexChars[j * 2] = hexArray[v >>> 4]; 
      hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
     } 
     return new String(hexChars); 
    } 

    private AESCryptt() { 
    } 
} 

、あなたがそのようにそれを呼び出すことができます。

try { 
     header = AESCryptt.encrypt("the key is fixed is this case",header); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
     System.out.println("eee , exception during encrypt log in data . . . ."); 
    } 
2

あります。これは、暗号化がの文字列ではなく、のデータバイト指向であるため意味をなさない。

ベース64 "tATTXSdXI4w0oiu/fzgpyA=="
16進数:B404D35D2757238C34A22BBF7F3829C8(16バイト)。

あなたは、コードのデータバイトにBase64でデコードする必要があります。

AES.setKey(""); 
final String strToDecrypt = "tATTXSdXI4w0oiu/fzgpyA=="; 
AES.decryptbyte(toBytes(strToDecrypt.toCharArray())); 

はまた、それが誤りである、上記のコードは、キーの空の文字列を持っていることに注意してください。

+0

サーバからの応答はBase64エンコーディングであり、それをStringに入れてから、それを解読するバイトの配列にします。この場合、例外を取り除き、Stringを処理する方法をアドバイスします。 Base64について私はサイト:http://aesencryption.net/で試してみることができます。 キーはあらかじめ定義されたキーを設定するためだけに.setKey( "")です check setKey()上記。 アドバイスお願いします。 –

+1

暗号化プリミティブはデータバイトを取り込み、データバイトを生成します。暗号化の前と後でエンコーディングを追加する実装がいくつかありますが、これは暗号化の部分ではありません。あなたが問題を抱えているように見えるのはエンコード部分だと思われます。実際には、文字列とそのエンコーディングの詳細、Base64、なぜそれが使われているのか、16進数でプレーンなデータバイトを学ぶために時間を取る必要があります。 – zaph

+0

暗号化の種類をAES/ECB/ZerobytePadddingに変更することで、Base64とbyte [] の変換に問題があり、復号化操作を行うことで解決します。 –