2016-05-24 14 views
3

私はAESCrypt(gradle :compile 'com.scottyab:aescrypt:0.0.1') を使ってデータを暗号化して解読します。javax.crypto.BadPaddingException AES

TextView tv=(TextView)findViewById(R.id.demotext); 
    String encrypted="",decrypted=""; 
    try { 
     encrypted = AESCrypt.encrypt("password","This is the best thing to go by"); 

     decrypted = AESCrypt.decrypt("password",encrypted); 
    } catch (GeneralSecurityException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("EncryptedData:"+encrypted); 
    System.out.println("DecryptedData:"+decrypted); 
    tv.setText("Encrypted:"+encrypted +"\n"+"Decrypted:"+decrypted); 

この場合、コードは完全に正常に動作し、復号化されたテキストと同じ入力が得られます。

しかし、私はスクリーンショットに示すように、サイトhttp://aesencryption.net/から同じ方法(AES)を使用して、すでに暗号化された文字列を使用しよう:

enter image description here

などのテキストを暗号化されたペーストをコピーします。

decrypted = AESCrypt.decrypt("password","sttA+FbNm3RkTovjHI8CcAdStXiMl45s29Jqle+y+pA="); 

そして、私はというエラーを取得するコードを実行します。

javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT 

enter image description here

しかし、私は同じ場所に復号化されたテキストを使用する場合は、以下のスクリーンショットのように、それが正常に動作します。おそらくによるアルゴリズムへ

enter image description here

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { 
     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
     byte[] decrypted = cipher.doFinal(encrypted); 
     return decrypted; 
    } 
+0

で保護されたAESキーで暗号化されます。なぜこれはあなたにとって興味深いのでしょうか?あなたが参照しているサイトはひどいです。それは互換性のない2つの言語で非常に安全なコードを伝播しません。 –

+0

私は1MB jsonのように暗号化し、Android Mobileに保存したいと考えています。 – erluxman

+0

** [ECBモード](http://crypto.stackexchange.com/q/14487/13022)**を絶対に使用しないでください。それは決定論的であり、したがって意味的に安全ではありません。少なくとも、[CBC](http://crypto.stackexchange.com/q/22260/13022)や[CTR](http://crypto.stackexchange.com/a/2378/)のようなランダム化モードを使用する必要があります13022)。あなたの暗号文を認証して、[パディング・オラクル攻撃](http:// crypto。stackexchange.com/q/18185/13022)は不可能です。これは、GCMやEAXなどの認証モードや[暗号化MAC](http://crypto.stackexchange.com/q/202/13022)スキームで行うことができます。 –

答えて

1

これはAESCrypt

private static SecretKeySpec GenerateKey (final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {     
    final MessageDigest digest = MessageDigest.getInstance (HASH_ALGORITHM); 
    byte [] bytes = password.getBytes ("UTF-8"); 
    digest.update (bytes, 0, bytes.length); 
    byte [] key = digest.digest(); 

    log ("SHA-256 key" key); 

    SecretKeySpec secretKeySpec = new SecretKeySpec (key, "AES"); 
    secretKeySpec return; 
    } 

におけるアルゴリズムであり、これは(Javaの)であるSecretKeySpec

にパスフレーズ 'パスワード' を変換します例aesencryption.net

sha = MessageDigest.getInstance ("SHA-1"); 
key = sha.digest (key); 
key = Arrays.copyOf (key, 16); // Use only first 128 bit 
SecretKey = new SecretKeySpec (key, "AES"); 

最初のものはSHA256のハッシュを適用し、2番目のSHA-1は16バイトまでを完了した後に適用されるため、キーは異なります。

あなたは正しい方法でAESを暗号化して解読していると思います。何も変更する必要はありません。

しかし、aesencryption.netと互換性がある場合は、同じ鍵生成アルゴリズムを実装する必要があります。コードはあまり良くありません。私は、私も魔女がプライベートユーザーデータを保存するために必要なAndroidアプリから抽出された自分自身のコードを提供することができます

//Code from aesencryption.net 
// Generate key 
MessageDigest sha = null; 
key = myKey.getBytes ("UTF-8"); 
sha = MessageDigest.getInstance ("SHA-1"); 
key = sha.digest (key); 
key = Arrays.copyOf (key, 16); // Use only first 128 bit 
SecretKey = new SecretKeySpec (key, "AES"); 

public static String encrypt (String strToEncrypt) { 
    Cipher cipher = Cipher.getInstance ("AES/ECB/PKCS5Padding"); 
     cipher.init (Cipher.ENCRYPT_MODE, SecretKey); 
    Base64.encodeBase64String return (cipher.doFinal (strToEncrypt.getBytes ("UTF-8")))); 
} 

public static String decrypt (String strToDecrypt) { 
    Cipher cipher = Cipher.getInstance ("AES/ECB/PKCS5PADDING"); 
    cipher.init (Cipher.DECRYPT_MODE, SecretKey); 
    return new String (cipher.doFinal (Base64.decodeBase64 (strToDecrypt)))); 
} 

を要約してみてください。データは、あなたが彼らのコードを知っていないいくつかのオンライン暗号化に書いたコードを比較しないでくださいユーザーパスフレーズ

public static String SIMMETRICAL_ALGORITHM = "AES"; 

//Generate cipher key with user provided password 
private static String getPassphraseSize16(String key) { 
    if (TextUtils.isEmpty(key)) { 
     return null; 
    } 
    char controlChar = '\u0014'; 
    String key16 = key + controlChar; 
    if (key16.length() < 16) { 
     while (key16.length() < 16) { 
      key16 += key + controlChar; 
     } 
    } 
    if (key16.length() > 16) { 
     key16 = key16.substring(key16.length() - 16, key16.length()); 
    } 
    return key16; 
} 

//AES cipher with passphrase 
public static byte[] encrypt(byte[] message, String passphrase) 
     throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
    String passphrase16 = getPassphraseSize16(passphrase); 

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM); 
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM); 
    cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
    byte[] encoded = cipher.doFinal(message); 

    return encoded; 
} 

//AES decipher with passphrase 
public static byte[] decrypt(byte[] encodedMessage, String key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
    String passphrase16 = getPassphraseSize16(key); 

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM); 
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM); 
    cipher.init(Cipher.DECRYPT_MODE, secretKey); 
    byte decoded[] = cipher.doFinal(encodedMessage); 

    return decoded; 
} 
+0

というショットを付けるので、キーを生成してそれを使用し、直接使用しないことを意味するでしょうか? – erluxman

+0

私はあなたが例として – pedrofb

+0

と同じ方法でAESCrypt.encryptとAESCrypt.decryptを使うことができると思います。私は何を変更/編集すべきかを明確にすることができますか? – erluxman

関連する問題