2017-04-16 4 views
0

私のAndroidアプリケーションでは、1行のテキストを暗号化して解読する機能があります。暗号 "PBEWithMD5AndDES"は安定していますか?

私はjavax.cryptoの経験がありませんが、私はこの回答を見つけましたEncrypt Password in Configuration Files?と同様のものを実装しました。

コード:

public String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException { 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD)); 
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
    pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, ITERATIONS)); 
    return Base64.encodeToString(pbeCipher.doFinal(property.getBytes("UTF-8")), Base64.DEFAULT); 
} 

public String decrypt(String property) throws GeneralSecurityException, IOException { 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD)); 
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
    pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, ITERATIONS)); 
    return new String(pbeCipher.doFinal(Base64.decode(property, Base64.DEFAULT)), "UTF-8"); 
} 

私はそれをテストし、それが正常に動作します。しかし、私に迷惑をかけることが1つあります。これらのメソッドは、GeneralSecurityException,UnsupportedEncodingExceptionIOExceptionを投げ捨てることができます。

質問:テキストが正常に暗号化されたときがあった場合可能性がありますが、いくつかの状況(新しいVMまたはそのような何かを持つ新しいAndroidのバージョン)の後decrypt方法はGeneralSecurityExceptionまたはIOExceptionをスローしますとアプリがそれを解読することはできませんテキスト?

+0

...あなたはそれをインポートし、それを使用し、完全な作業です。今日ではDESとMD5を使用すべきではないと考えています。残念ながら、私はPBEWithMD5AndDESを維持するためにGoogleから各ベンダーに要件があるとは思わないので、この回答は本当にお答えできません。 –

+0

将来どのようなベンダーが何をするのか、誰がどのように言うことができますか? @ArtjomB。 –

+0

ああ、私は知っている、と私は理解するように、すべてのアルゴリズムは将来的に削除することができますので、Cipherを使うのは「安全」ではないのですか? –

答えて

2

例外として、これらは突然正しい入力で投げられるべきではありません。 NoSuchAlgorithmException - アルゴリズムがもうサポートされていない場合は、GeneralSecurityExceptionのサブクラスをスローする必要があります。

任意のAPI - この場合、暗号化サービス - は取り消すことができます。しかし、これはどの関数にも当てはまります。その場合、あなたの解空間は空になります。この場合、少なくともアルゴリズムは明確に定義されているので、オープンソースなどのコードをいつでも再インポートすることができます。もちろん、このような古いアルゴリズムは、もはや使用すべきではないので撤回することができますが、JavaとAndroidは非推奨の関数を削除するのではなく、下位互換性のために使用されます。


はい、アルゴリズムは安定ですが、私はあなたがより良い理解を持っている単語安定から「B」を削除する必要がありますね。

DESは、セキュリティに敏感な素材にはもう使用しないでください。 3キーDES EDE でもセキュリティに近いものを提供するために使用できます。

PBKアルゴリズムで使用されているPBKDF1と同じように、それほど拡張されていません。

GCMモードのAESなどの別の暗号を、PBKDF2などの最新のパスワードハッシュとともに使用するか、さらにはArgon2などのものを使用する必要があります。

あなたのSALT定数 - これは大文字の大文字からの定数です - その場で生成する必要があります。一定の塩を使用することは目的を破る。


しかし、基本的には、暗号化をあるレベルまで理解してから活用する必要があります。コピー/ペーストのセキュリティは存在しないので、誰かに相談する必要があります。

+0

私は以前に暗号を使っていませんでしたが、基本的な暗号化を追加して、アプリからSharedPreferencesを抽出できるが、Base64より難しいものを暗号化できない大部分の "ハッカー"を除外したかったのです。 –

+0

さて、DESは少し上手くして64番の鍵(鍵が全くない)ですが、PKCS#5を試してみて、PBKDF2とAESを実装する方法を見つけてください。 Base64は暗号化方式ではなく、*符号化方式です。 –

0

DES(CBC)モードを使用するため、簡単に解読できます。 DESの有効なキーサイズは56ビットのみです。したがって、鍵と鍵は、(PBKDF1)鍵の導出に関係なく強制的に強制することができます。

MD5は、PBKDF1内で使用されているときには問題がありませんが、パスワードには十分なエントロピーが含まれていれば問題ありません。

可能であれば、PBKDF2とAESを使用してパスワードベースの暗号化(PBE)にアップグレードする必要があります。 PBEは通常CBCモードの暗号化を使用するため、トランスポートプロトコルには適していません。

それは確かに、いくつか/あなたのAndroidベンダーは将来のある時点でPBEWithMD5AndDESはを削除する可能性がある

package com.example.siman.friend_pro; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.security.spec.AlgorithmParameterSpec; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.KeySpec; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.PBEParameterSpec; 

import static javax.crypto.Cipher.DECRYPT_MODE; 
import static javax.crypto.Cipher.ENCRYPT_MODE; 
import static javax.crypto.Cipher.getInstance; 

public class Encryptor4j 
{ 
    private static byte[] salt = { 
      (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32, 
      (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03 
    }; 
    private static Cipher ecipher; 
    private static Cipher dcipher; 
    private static String Property = "youkey"; 
    private static int iterationCount = 19; 

    public static String encrypt(String Text) 
    { 
     String returnvalue=null; 
     try { 
      returnvalue = Encryptor4j.form1(Text); 
     } 
     catch (NoSuchAlgorithmException | InvalidKeySpecException | 
       NoSuchPaddingException | InvalidKeyException | 
       InvalidAlgorithmParameterException | IllegalBlockSizeException | 
       BadPaddingException | IOException e) { 
      e.printStackTrace(); 
     } 
     return returnvalue; 
    } 
    public static String decrypt(String Text) 
    { 
     String returnvalue=null; 
     try { 
      returnvalue = Encryptor4j.form2(Text); 
     } 
     catch (NoSuchAlgorithmException | InvalidKeySpecException | 
       NoSuchPaddingException | InvalidKeyException | 
       InvalidAlgorithmParameterException | IllegalBlockSizeException | 
       BadPaddingException | IOException e) { 
      e.printStackTrace(); 
     } 
     return returnvalue; 
    } 


    private static String form1(String Text) 
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException 
    { 
     //Key generation for enc and desc 
     KeySpec keySpec = new PBEKeySpec(Property.toCharArray(), salt, iterationCount); 
     SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); 
     // Prepare the parameter to the ciphers 
     AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount); 

     //Enc process 
     ecipher = getInstance(key.getAlgorithm()); 
     ecipher.init(ENCRYPT_MODE, key, paramSpec); 
     String charSet = "UTF-8"; 
     byte[] in = Text.getBytes(charSet); 
     byte[] out = ecipher.doFinal(in); 
     String encStr = new String(android.util.Base64.encode(out,0)); 
     //String encStr = new String(Base64.getEncoder().encode(out)); 
     return encStr; 
    } 

    private static String form2(String Text) 
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, IOException 
    { 
     //Key generation for enc and desc 
     KeySpec keySpec = new PBEKeySpec(Property.toCharArray(), salt, iterationCount); 
     SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); 
     // Prepare the parameter to the ciphers 
     AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount); 
     //Decryption process; same key will be used for decr 
     dcipher = getInstance(key.getAlgorithm()); 
     dcipher.init(DECRYPT_MODE, key, paramSpec); 
     //byte[] enc = Base64.getDecoder().decode(encryptedText); 
     byte[] enc = android.util.Base64.decode(Text.getBytes(),0); 
     byte[] utf8 = dcipher.doFinal(enc); 
     String charSet = "UTF-8"; 
     String plainStr = new String(utf8, charSet); 
     return plainStr; 
    } 
} 
関連する問題