使用反射擦洗String
使用与使用密码String
一样安全吗?char[]
从安全方面来看,通常认为最好的做法是char[]
用于存储/传递密码,因为可以在代码中尽快将其内容清零,这可能在垃圾收集清理它并重用内存之前很重要(擦除所有痕迹),限制内存攻击的时间窗口。
但是,它char[]
不如. _String
String
String
char[]
下面是一种使用反射将String
.
这种方法是否“OK”,是否达到了使密码与密码String
一样安全的目标char[]
?
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);
}
这是一个简单的测试:
String str = "password";
scrub(str);
System.out.println('"' + str + '"');
输出:
""
注意:您可以假设密码不是String
常量,因此调用此方法不会对实习字符串产生不利影响。
另外,为了简单起见,我已经离开了这个方法是一个相当“原始”的状态。如果我要使用它,我不会声明抛出的异常(尝试/捕获/忽略它们)并重构重复的代码。