String使用上的安全问题: 为什么在密码问题上char[]优先于String?
2014-04-19 23:02
337 查看
1.字符串有一个结束标识符(‘\0’),
比如“学java”的内存空间占6个字符,长度为5(长度不仅结束标识符);
长见识了。之前还没意识这个安全问题。
转载于http://blog.csdn.net/maijunjin/article/details/21925309
在Swing中,密码域(JPasswordField)用
In Swing, the password
field has a
method instead of the usual
method. Similarly, I have come across a suggestion not to use
to handle passwords. Why does
a threat to security when it comes to passwords?
It feels inconvenient to use
String在Java中是不可变对象,这就意味着一旦创建了一个字符串,如果另一个进程把尝试内存的数据导出(dump),在GC进行垃圾回收之前该字符串会一直保留在内存中,那么该进程就可以轻易的读取到该字符串。
而对于数组,可以在该数组处理它之后再显示地擦掉数组中内容,可以以任何方式把数组内容覆盖掉,即使是GC触发前密码也不会出现在系统的任何地方。
所以,这是从安全角度来选择的,但是即便是用
Strings are immutable. That means once you've created the string, if another process can dump memory, there's no way (aside from reflection) you can get rid of the data before GC kicks in.
With an array, you can explicitly wipe the data after you're done with it: you can overwrite the array with anything you like, and the password won't be present anywhere in the system, even before garbage
collection.
So yes, this is a security concern - but even using
window of opportunity for an attacker, and it's only for this specific type of attack.
EDIT: As noted in comments, it's possible that arrays being moved by the garbage collector will leave stray copies of the data in memory. I believe this is implementation-specific - the GC may clear
all memory as it goes, to avoid this sort of thing. Even if it does, there's still the time during which the
the actual characters as an attack window.
从另一方面来,若是普通的字符串,有时你会不经意间打印密码到日志中或者其他不安全的地方,而char
参考一下这段代码:
输出结果:
While other suggestions here seem valid, there is one other good reason. With plain
have much higher chances of accidentally printing the password to logs, monitors or some other insecure place.
less vulnerable.
Consider this:
Prints:
引用官方的文档,Java加密体系结构指南说到char[]
vs String。在对象
字符数组(
尽管使用
比如“学java”的内存空间占6个字符,长度为5(长度不仅结束标识符);
长见识了。之前还没意识这个安全问题。
转载于http://blog.csdn.net/maijunjin/article/details/21925309
问题
在Swing中,密码域(JPasswordField)用getPassword()函数(用来返回
char[])取代
getText()函数(返回字符串)。在工作中我得到类似的建议是不要用字符串去处理密码相关的问题,为什么涉及到密码问题时字符串会对安全构成威胁呢?(译注:这是提问者在Stackoverflow提了问题,他觉得用char[]处理密码并没有String方便,但为什么还要推荐使用char[]处理呢?下面是几个比较精彩的回答)。
Why
is char[] preferred over String for passwords?
In Swing, the passwordfield has a
getPassword()(returns
char[])
method instead of the usual
getText()(returns
String)
method. Similarly, I have come across a suggestion not to use
Strings
to handle passwords. Why does
Stringpose
a threat to security when it comes to passwords?
It feels inconvenient to use
char[].
回答1
String在Java中是不可变对象,这就意味着一旦创建了一个字符串,如果另一个进程把尝试内存的数据导出(dump),在GC进行垃圾回收之前该字符串会一直保留在内存中,那么该进程就可以轻易的读取到该字符串。而对于数组,可以在该数组处理它之后再显示地擦掉数组中内容,可以以任何方式把数组内容覆盖掉,即使是GC触发前密码也不会出现在系统的任何地方。
所以,这是从安全角度来选择的,但是即便是用
char[]也只是降低被攻击的概率而已,还是会有一些特定的手法攻破数组处理的密码。
Strings are immutable. That means once you've created the string, if another process can dump memory, there's no way (aside from reflection) you can get rid of the data before GC kicks in.
With an array, you can explicitly wipe the data after you're done with it: you can overwrite the array with anything you like, and the password won't be present anywhere in the system, even before garbage
collection.
So yes, this is a security concern - but even using
char[]only reduces the
window of opportunity for an attacker, and it's only for this specific type of attack.
EDIT: As noted in comments, it's possible that arrays being moved by the garbage collector will leave stray copies of the data in memory. I believe this is implementation-specific - the GC may clear
all memory as it goes, to avoid this sort of thing. Even if it does, there's still the time during which the
char[]contains
the actual characters as an attack window.
回答2
从另一方面来,若是普通的字符串,有时你会不经意间打印密码到日志中或者其他不安全的地方,而char[] 就没那么显而易见。
参考一下这段代码:
Stringyou
have much higher chances of accidentally printing the password to logs, monitors or some other insecure place.
char[]is
less vulnerable.
Consider this:
[code]public static void main(String[] args) { Object pw = "Password"; System.out.println("String: " + pw); pw = "Password".toCharArray(); System.out.println("Array: " + pw); }
Prints:
[code]String: Password Array: [C@5829428e
回答3
引用官方的文档,Java加密体系结构指南说到char[]vs String。在对象
java.lang.String中收集和存储密码看似符合逻辑,但是字符串对象是不可变的,没有任何方法可以改变(重写)或清空内容。这一特性使得字符串对象不适合存储安全敏感信息,比如用户密码。你应当使用一个字符数组来代替,以便收集和存储安全敏感的信息。安全编码指南4.0也提到了类似的问题。
回答4
字符数组(char[])在使用之后里面的元素可以被清除,字符串并不如此。如果有人能以某种方式看到内存映像,如果字符串被使用了,它们可以以纯文本方式看到密码。但如果是
char[], 看到的是清除后的数据(用0替换的数据),这种方式是安全的。
最后的思考
尽管使用char[]并不能保证足够安全,但我也建议使用hash’d或者加密的密码来代替普通的文本字符串密码,而且使用完后立即清除。
相关文章推荐
- 为什么Java中的密码优先使用 char[] 而不是String?
- 为什么在密码问题上char[]优先于String?
- 为什么在密码问题上char[]优先于String?
- 为什么在密码问题上char[]优先于String?
- shiro-密码比较的设计 CredentialsMatcher -为什么Java中的密码优先使用 char[] 而不是String?
- 为什么在密码问题上char[]优先于String?
- Java中的密码优先使用 char[] 而不是String
- 在JAVA开发中,当获取到密码字段后,为什么将其优先赋值于char[]类型的实例而不是String 类型的?
- Java中的密码优先使用 char[] 而不是String
- MSDE安装出问题:为了安全起见,要求使用强SA密码。请使用SAPWD开关提供同一密码
- 为什么使用字符数组保存密码比使用String保存密码更好?
- 为什么使用字符数组保存密码比使用String保存密码更好?(Why character arr...
- 利用Jquery让返回的各类数据(string、集合(List<>)、类)以Json数据格式返回,为什么要用到result.d (JQuery ajax 返回数据 使用 .d 的问题)
- 为什么使用字符数组保存密码比使用String保存密码更好?
- Android安全输入设计与思考,android设计思考 为什么使用安全键盘? 安全的输入 各大公司的安全键盘设计 开始自定义安全键盘 安全键盘还需要注意的
- Mac版 有道云笔记登陆出现问题 (使用用户名密码方式登陆)
- 使用 Request.QueryString 接受参数时,跟编码有关的一些问题
- 为什么会出现数据安全问题?资源抢夺有哪些解决办法
- selenium学习笔记- selnium.RunScript(string script) 方法的使用 及有关自动化测试文本编辑器未解决的问题
- 一个关于使用String做锁的问题(PS:不要使用string做锁)