Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我们从控制台读取字符数组而不是字符串中的密码_Java_Console - Fatal编程技术网

Java 为什么我们从控制台读取字符数组而不是字符串中的密码

Java 为什么我们从控制台读取字符数组而不是字符串中的密码,java,console,Java,Console,可能重复: 当我在为OCPJP做准备的时候,我偶然碰到了一个主题——“从控制台读取用户输入” 有一个例子,它在String引用中读取username,而在char[]数组中读取password,但我不明白它为什么使用char数组。。代码如下:- Console console = System.console(); String username = console.readLine("User Name? "); char[] password = console.readPassword

可能重复:

当我在为OCPJP做准备的时候,我偶然碰到了一个主题——“从控制台读取用户输入”

有一个例子,它在
String
引用中读取
username
,而在
char[]
数组中读取
password
,但我不明白它为什么使用char数组。。代码如下:-

Console console = System.console();

String username = console.readLine("User Name? ");
char[] password = console.readPassword("Password? "); 
这使我产生了怀疑。。为什么我们不使用字符串引用来存储密码。由于
字符串
是不可变的,
因此读取字符串中的密码必须更安全,因为它的内容不能因此而更改

那么,在
char[]
数组中读取
password
有什么意义呢


有人能解释一下这个问题吗?

由于字符串是不可变的,所以在应用程序处于活动状态时,它们不能被覆盖并保留在内存中。另一方面,
char
数组可以清除所有密码信息。

正如您所说,字符串是不可变的,这意味着一旦您创建了字符串,如果另一个进程可以转储内存,那么在GC启动之前,您无法(好的,可以使用反射)清除数据


使用数组,您可以在处理完数据后显式地擦除数据:您可以用任何您喜欢的内容覆盖数组,并且即使在垃圾收集之前,密码也不会出现在系统中的任何位置。

我认为这样做是为了在不再需要时通过覆盖来清除内存中的密码。至少在Java中,如果您使用字符串,那么内存中可能会有剩余的副本

如果使用for循环覆盖char数组并将每个值设置为0,我认为内存中不会有任何剩余副本。

来自:

安全注意事项:如果应用程序需要读取密码或其他安全数据, 它应该使用
readPassword()
readPassword(字符串、对象…)
并手动归零 处理后返回的字符数组,以最小化 内存中的敏感数据

这只是为了防止其他应用程序(如键盘记录器等)访问密码


此外,如果您使用
String
,因为它们是不可变的,修改它们将在内存中创建副本。在这种情况下,使用
char[]
将节省您的时间。因为它们是可变的,它们不会创建副本,您可以在处理后将其设为null。

不了解char[]可以不同于键盘记录程序的字符串…@caarlos0实际上,这不会阻止键盘记录程序,但会减少其读取内容的机会,因为副本不可用,数据将被取消。如果我错了,请纠正我,但是,我认为键盘记录程序会捕获键盘事件..所以,无论您使用的数据类型是什么..对吗?我相信这只会阻止人们从内存转储中获取字符串。由于焦点问题,他们无法直接从输入中获取密钥。相反,他们必须读取内存。嗯,在这种情况下,你是对的。谢谢。至少这是使用字符数组作为密码的目的。但是,我不确定是否考虑了堆碎片整理虚拟内存、交换等等都是真的。若对堆进行碎片整理导致字符数组在进程的内存空间内移动,那个么旧位置上的内容会被删除吗?我相信这取决于GC特定的实现。。。