我公司的员工需要通过我制作的程序修改SQL Server数据库中的数据.该程序首先使用Windows身份验证,我要求DBA为此特定用户提供对所述数据库的写访问权限.
他们不愿意这样做,而是给我的 Windows用户帐户提供写访问权限.
因为我相信这个人但是还不足以让他在我的会话打开的情况下工作90分钟,我只会在我的程序中添加一个登录提示,要求输入用户名和密码,然后使用它登录到SQL Server.我会登录,并相信我的应用程序让他只做他需要的东西.
然而,这会带来很小的安全风险.该密码字段教程在太阳 Oracle的网站指出,密码应保持在内存中所需要的最短时间,并为此目的,该getPassword方法返回一个char[]数组,一旦你用它做,你可以零.
但是,Java的DriverManager类只接受String对象作为密码,所以一旦我完成它,我将无法处理密码.而且由于我的应用程序在分配和内存要求方面非常低,谁知道它能在内存中存活多久?如上所述,该程序将运行相当长的时间.
当然,我无法控制任何的SQL Server的JDBC类与我的密码,但我希望我能控制什么我做我的密码.
有没有一种可靠的方法来破坏/清除StringJava对象?我知道两者都有点违背语言(对象破坏是非确定性的,String对象是不可变的),并且System.gc()有点不可预测,但仍然存在; 任何的想法?
jta*_*orn 21
所以,这是坏消息.我很惊讶没人提到它.与现代垃圾收集器,甚至整个char []概念被打破.无论你是使用String还是char [],数据最终都会存在于内存中,以便知道多长时间.这是为什么?因为现代的jvms使用世代垃圾收集器,简而言之就是在整个地方复制对象.所以,即使你使用了char [],它使用的实际内存也可以被复制到堆中的各个位置,在任何地方都会留下密码的副本(并且没有高性能的gc会将旧内存清零).所以,当你将最后的实例归零时,你只是将内存中的最新版本归零.
长话,简而言之,没有防弹方式来处理它.你几乎要相信这个人.
Mar*_*ers 11
我只能想到使用反射的解决方案.您可以使用反射来调用使用共享字符数组的私有构造函数:
char[] chars = {'a', 'b', 'c'};
Constructor<String> con = String.class.getDeclaredConstructor(int.class, int.class, char[].class);
con.setAccessible(true);
String password = con.newInstance(0, chars.length, chars);
System.out.println(password);
//erase it
Arrays.fill(chars, '\0');
System.out.println(password);
Run Code Online (Sandbox Code Playgroud)
对于任何认为这是一个防故障甚至有用的预防措施的人,我鼓励你阅读jtahlborn的答案,至少有一个警告.
如果绝对必要,请保留对字符串的 WeakReference,并继续吞噬内存,直到强制对字符串进行垃圾回收,您可以通过测试弱引用是否已变为 null 来检测。这可能仍然将字节留在进程地址空间中。垃圾收集器再搅动几次可能会给您带来安慰吗?因此,在原始字符串弱引用被清空后,创建另一个弱引用并搅动直到它被清零,这意味着完整的垃圾收集周期已完成。
不知何故,我必须添加哈哈,即使我上面的回答是完全严肃的:)