小编典典

Java char []数组jPasswordField处理和SQL更新语句

sql

TLDR;通过String类解析char数组是否String.valueOf(charArray);比使String类的对象更安全?我试图理解/扩展以下内容中的讨论:
为什么密码比字符串更喜欢char []?

我最近刚刚阅读了很多有关如何在Java中“安全地”处理密码的知识,但是仍然有一个我不太了解如何解决的问题。当您从jPasswordField输入密码时,它以字符数组的形式出现。这非常好,因为您可以比零等待垃圾收集器清理字符串和诸如此类的东西更容易地用零覆盖数组。

我的问题出在以下方面:当我想在SQL中运行一条update语句来更新密码时,我简直不能放入char数组,因为它的格式错误。当我做类似的事情时Arrays.toString(arrayName);,使用format:

[e, a, c, h, o, f, t, h, e, l, e, t, t, e, r, s]

我可以使用…将它放入数据库列的唯一方法是…假设VARCHAR(100)不含所有逗号,并且空格似乎是写类似以下内容:

String stringPassword="";
int i=0;
for(char a:newPassword){
    stringPassword=stringPassword+newPassword[i];
    i++;
}

如果我做这样的事情,我不仅会破坏整个使用char数组的观点吗?谷歌搜索并没有真正帮助我解决这一问题。

在此先感谢您的时间。

编辑1:感谢KKaar的可能的解决方案:

char[] passwordArray;
String.valueOf(passwordArray);

就我需要的目的而言,这在语法上很好用,但是我仍然不知道它是否安全。如果我String.valueOf(passwordArray)使用prepareStatement语法进行编写,它不会从中生成变量,但仍会通过String类解析值。这是否意味着它仍然处于危险之中,还是安全的?


阅读 214

收藏
2021-04-22

共1个答案

小编典典

String.valueOf(charArray) 创建一个String,并且同样不安全。

如今,人们可以使用JDBC:

char[] password = ...;
try (PreparedStatement stmt = con.prepareStatement("...")) {
    Reader reader = new CharArrayReader(password);
    stmt.setCharacterStream(1, reader);
    stmt.executeUpdate();
    stmt.clearParameters();
}
Arrays.fill(password, ' ');

这样可以确保在执行此代码后,没有任何对象漂浮在周围以进行垃圾收集,这可能会显示密码。

当然,只要JDBC驱动程序不泄漏即可。该 clearParameters 似乎有点过头了,但谁知道。

CharArrayReader并 没有 复制传递的数组,因此这是安全的了。


要求提供具体代码:

String sql = "UPDATE teachers SET password=? WHERE firstname=? AND lastname=?";
try (PreparedStatement pStat = con.prepareStatement(sql)) {
    Reader reader = new CharArrayReader(newPassword);
    pStat.setCharacterStream(1, reader);
    pStat.setString(2, firstName);
    pStat.setString(3, lastName);
    pStat.executeUpdate();
    pStat.clearParameters();
}
Arrays.fill(newPassword, ' ');

由于该语句应关闭,因此我可以自由使用局部变量。

2021-04-22