現在、この投稿に影響を受けた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