3

現在、この投稿に影響を受けたAndroidのAES 256を使用して対称暗号化/復号化を実装しています: Java 256bit AES Encryption 私の実装の目的は、データベースのデータを暗号化することです。私がchar []パスワードとり、次のコンストラクタを使用して鍵生成のためにすべてのメッセージに対して1つのキーとランダムIVを使用するAndroid AESパスワードベースの暗号化

public Cryptography(char[] password) throws NoSuchAlgorithmException, 
     InvalidKeySpecException, NoSuchPaddingException { 

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); 
    KeySpec spec = new PBEKeySpec(password, salt, 1024, 256); 
    secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); 
    cipher = Cipher.getInstance(AES/CBC/PKCS5Padding); 
} 

私はアンドロイドで私の活動を開始するときに、私は私の暗号クラスの新しいインスタンスを初期化し、したがって、生成されたキーを取得します。ソルトは16バイトの固定ランダムバイト[]です。つまり、私はいつも同じ鍵を取得します。その理由は後で。

今、私は1つのアクティビティでオブジェクトを得た後、私は、次の暗号化を使用し、常に同じキーを持つメソッドを復号化することができます

public byte[] encrypt(String cleartext) throws InvalidKeyException, 
     IllegalBlockSizeException, BadPaddingException, 
     UnsupportedEncodingException, InvalidParameterSpecException { 

    cipher.init(Cipher.ENCRYPT_MODE, secretKey); 

    byte[] encText = cipher.doFinal(cleartext.getBytes(CHARSET_NAME)); 
    byte[] iv = cipher.getParameters() 
      .getParameterSpec(IvParameterSpec.class).getIV(); 

    byte[] enc = new byte[IV_SIZE + encText.length]; 

    for (int i = 0; i < enc.length; i++) { 
     if (i < IV_SIZE) 
      enc[i] = iv[i]; 
     else if (i < enc.length) 
      enc[i] = encText[i - IV_SIZE]; 
    } 

    return enc; 
} 

public String decrypt(byte[] encryptedText) throws InvalidKeyException, 
     InvalidAlgorithmParameterException, UnsupportedEncodingException, 
     IllegalBlockSizeException, BadPaddingException { 

    byte[] iv = new byte[IV_SIZE]; 
    byte[] dec = new byte[encryptedText.length - IV_SIZE]; 

    for (int i = 0; i < encryptedText.length; i++) { 
     if (i < IV_SIZE) 
      iv[i] = encryptedText[i]; 
     else if (i < encryptedText.length) 
      dec[i - IV_SIZE] = encryptedText[i]; 
    } 

    cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); 

    return new String(cipher.doFinal(dec), CHARSET_NAME); 
} 

あなたが見ることができるように、私は暗号文と一緒に新鮮な新しいIVを保存毎回メッセージを暗号化します。

結論:私は、データベーステーブルの1つの暗号化キー、1つのランダムソルト、新しいIV for EVERYフィールドを使用します。

最初に、データベーステーブルの1つのフィールドを暗号化し、必要な塩とIVを暗号文とともに、または少なくとも1つのテーブル行に保存するたびに、新しい塩と新しいIVで新しい鍵を生成したかったのです。しかし、私が上記のようにした理由は、Androidデバイスで鍵を生成するのに時間がかかるからです。私はエミュレータで試しましたが、キーを生成するのに約2秒かかりました。これは、アクティビティーが開始されたときにただ1つの鍵を生成した理由です。

最終的に私の質問: 私のアプローチでは、1つのキーですべてのメッセージに対して新鮮なランダムIVを使用すれば十分ですか?現在、パフォーマンスとのバランスを保ちながら、できるだけ安全にする別の方法はありません。

私が書いたことが十分明確であり、誰かがそれについて私に助言を与えることができることを希望します。

種類よろしく

xoidberg

答えて

1

私は質問が(xoidberg)あなたのためには関係ありませんが、それはいくつか他の人のための関連するかもしれないと考えています。

私が理解しているところでは、パスワードを使って(安全にランダムな)鍵を作るために塩を使います。すべてのユーザーがランダムな(異なる)塩を持っている場合 - それは問題ありません。それ以外の場合は問題がある可能性があります。

私はこれがあなたがしたことだと信じているので、(私にとっては)大丈夫と思われます。

私はちょうどあなたがいくつかの値(通常はパスワード)のハッシュ関数を保存するときに塩を使用したいと言いたいと思います。 MD5やSHAなどのハッシュ関数にはキーがありません。この目的のためにランダム性を追加する必要があります。これは塩を必要とする理由です。このため、この場合、通常は各値にランダムな塩が必要です(パスワードのハッシュを同じ塩で保存する場合、最も一般的なハッシュを検出し、ユーザーのパスワード最も一般的なハッシュは123456です)。あなたのケースでは、すべてのユーザーが独自の塩を必要とします。

IVについて - 本当に毎回ランダムなものが必要です(大丈夫です)。

関連する問題