リフレクションを使用してString
をスクラブすると、パスワードとしてchar[]
を使用すると安全ですか?リフレクションを使用して安全に文字列を使用してガベージコレクションの前に内容をスクラブする
char[]
をパスワードの保存/渡しに使用することが一般的にはベストプラクティスと考えられます。できるだけ早くその内容をゼロにすることができます。ガベージコレクションの前には、メモリは再使用され(すべてのトレースを消去します)、メモリ攻撃の時間枠を制限します。
はしかし、char[]
はString
ほど便利ではありませんので、必要に応じて、1は「スクラブ」String
は、これchar[]
と同様に安全String
を作ることができれば、それは便利だろう。
以下は、反射を使用してString
のフィールドをゼロにする方法です。
この方法は「OK」ですか、String
をパスワードとしてchar[]
と安全にするという目標を達成していますか?
String str = "password";
scrub(str);
System.out.println('"' + str + '"');
出力:
""
注:あなたはパスワードがString
定数でないと仮定することができるので、このメソッドを呼び出すと、有害なを持っていません。ここ
public static void scrub(String str) throws NoSuchFieldException, IllegalAccessException {
Field valueField = String.class.getDeclaredField("value");
Field offsetField = String.class.getDeclaredField("offset");
Field countField = String.class.getDeclaredField("count");
Field hashField = String.class.getDeclaredField("hash");
valueField.setAccessible(true);
offsetField.setAccessible(true);
countField.setAccessible(true);
hashField.setAccessible(true);
char[] value = (char[]) valueField.get(str);
// overwrite the relevant array contents with null chars
Arrays.fill(value, offsetField.getInt(str), countField.getInt(str), '\0');
countField.set(str, 0); // scrub password length too
hashField.set(str, 0); // the hash could be used to crack a password
valueField.setAccessible(false);
offsetField.setAccessible(false);
countField.setAccessible(false);
hashField.setAccessible(false);
}
は、簡単なテストですinterned Stringsに対する効果。
また、私はこのメソッドを簡単にするためにかなり「生の」状態にしておきます。私がそれを使用する場合、例外をスロー(try/catch/ignoring)し、リファクタリングを繰り返すコードを宣言しません。
文字をゼロにするようですが、JVMの実装にはそれほど依存しません。 – fge
メモリスヌーピング?それはファンタジー攻撃です。 NSAがネットワークトラフィックをスヌーピングするような、より現実的なものを心配しないでください。 – ZhongYu
「未定義の動作」を私に叫ぶ。龍、velociraptorsとブラックホールとの幸運:) – CodesInChaos