相关疑难解决方法(0)

为了安全起见,清除不同语言的内存

在学习Java时,我了解到Strings 对于存储密码不安全的,因为你无法手动清除与它们相关的内存(你不能确定它们最终会被gc'ed,内部字符串可能永远不会,甚至之后gc你不能确定物理内存内容真的被擦除了).相反,我使用char数组,所以我可以在使用后将它们清零.我试图在其他语言和平台上搜索类似的做法,但到​​目前为止我找不到相关的信息(通常我看到的是密码存储在字符串中的代码示例,没有提到任何安全问题).

我对浏览器的情况特别感兴趣.我经常使用jQuery,而我通常的做法就是将密码字段的值设置为空字符串而忘记它:

$(myPasswordField).val("");
Run Code Online (Sandbox Code Playgroud)

但我并不是100%确信它已经足够了.我也不知道用于中间访问的字符串是否安全(例如,当我$.ajax用来将密码发送到服务器时).至于其他语言,通常我没有提到这个问题(我特别感兴趣的另一种语言是Python).

我知道试图建立列表的问题是有争议的,但由于这涉及一个很大程度上被忽视的共同安全问题,恕我直言,这是值得的.如果我弄错了,我会很高兴知道从JavaScript(在浏览器中)和Python.我也不确定是在这里,在security.SE还是在程序员.SE,但由于它涉及安全执行任务的实际代码(不是概念性问题),我相信这个网站是最好的选择.

注意:在低级语言或明确支持字符作为原始类型的语言中,答案应该是显而易见的(编辑:不是很明显,正如@Gabe在下面的答案中所示).我要求那些"一切都是对象"或类似的高级语言,以及那些在幕后执行自动字符串实习的人(所以你可能会创建一个安全漏洞而不会意识到它,即使你'合理谨慎).

更新:根据相关问题的答案,即使char[]在Java中使用也不能保证是防弹的(或者就此而言是.NET SecureString),因为gc可能会移动数组,因此其内容可能会粘在内存中,即使在清除(SecureString至少保留在相同的RAM地址中,保证清除,但其消费者/生产者可能仍然留下痕迹).

我猜@NiklasB.是正确的,即使漏洞存在,漏洞利用的可能性很低,防止漏洞的难度很高,这可能是这个问题大多被忽视的原因.我希望我至少可以找到关于浏览器这个问题的一些参考,但谷歌搜索到目前为止一直没有结果(这个场景至少有一个名字吗?).

security string passwords memory-management

6
推荐指数
1
解决办法
825
查看次数

带动作命令的JPasswordField安全性

JPasswordField在我的程序中使用了一个.当我问getPassword(),我得到一个char[]数组.但是,当我添加ActionListenerJPasswordField,问getActionCommand(),我得到的密码作为String.此密码是否在事件对象中保存为String这不是一个安全问题吗?

java security swing jpasswordfield

6
推荐指数
1
解决办法
295
查看次数

用户可以使用char []而不是Servlet中的字符串来存储密码吗?

我阅读了几篇关于安全性的文章和帖子(注意 在Web应用程序中将输入密码与存储的哈希密码进行比较,或者为什么char []首选字符串用于密码?

由于从请求中检索参数值使用返回String的request.getParameter("passwordFieldName"),是否有任何选项可以从请求中检索参数作为char []?

java security passwords servlets

6
推荐指数
1
解决办法
983
查看次数

使用char数组而不是String建立数据库连接的问题

正如标题所说,我正在寻找一种方法来使用char []数组来建立JDBC连接,而不是从char []数组创建一个新的String对象,并使用它来建立连接.

因为char []数组比java中的字符串更安全,所以我一直希望在处理我的JPasswordField时尽可能保证安全.

在这种特殊情况下,我将获取JPasswordField的char []数组内容并尝试建立与数据库的JDBC连接.它运行得很好,但是我必须从char []数组创建一个新的String对象来实际调用getConnection方法.

有没有办法确保至少有一些安全性这样做,或者我只是被迫创建String对象并继续在方法中使用它?

这是我的代码:

/**
 * Construct a new DataManager object with it's own
 * connection to the database.
 *
 * @param ipAddress The IP address to the server on which MySQL is running.
 * @param port The port to use when connecting to MySQL.
 * @param databaseName The database name of the database to connect to.
 * @param username The username for a MySQL account with access to the …
Run Code Online (Sandbox Code Playgroud)

java jdbc

5
推荐指数
1
解决办法
451
查看次数

java垃圾收集可以安全清除垃圾数据吗?

这是一个内存数据安全性问题。
Java垃圾收集是否可以安全清除垃圾数据?

显然,在大块数据被垃圾回收之后,我再也无法检索它了,但是黑客仍然可以通过内存转储来检索数据吗?

java garbage-collection

5
推荐指数
2
解决办法
767
查看次数

清除所有线程中的数组

在Java中,建议char[]用于存储密码或其他敏感信息,以便在不再需要数据时能够手动清除它。

如何在所有线程中清除这样的数组?如果我理解正确,线程可能只会在其缓存中执行更改,而不会在共享内存中执行更改,因此以下操作将无法可靠地运行:

char[] password = ...
...
Arrays.fill(password, '\0');
Run Code Online (Sandbox Code Playgroud)
  • 这个假设是正确的还是线程总是写到共享内存?
  • 是否有必要使用volatile(或其他同步方式)确保共享内存已更新?
    • 是否需要事前发生关系,因为编译器/ JVM会由于优化而忽略内存同步?
  • 其他线程是否必须先建立先发生后关系才能从其缓存中清除阵列内容,还是可以忽略不计?可能是因为缓存将用于其他更频繁访问的数据,并且由于不再使用该数组,因此该数组将被丢弃。

编辑:char[]应该用于密码的语句是基于为什么为什么char []优于String?但是,再次查看之后,这也引起了一些争议。

java

5
推荐指数
1
解决办法
89
查看次数

如何安全地归零和释放 Android 应用程序使用的所有内存页面?

我是一名软件工程师,正在构建一个将由政府机构使用的 Android 应用程序。

我们合同中的一项要求是应用程序必须符合 FIPS 140。 https://en.wikipedia.org/wiki/FIPS_140

为了符合 FIPS,我们的应用程序必须在 android 应用程序关闭时将 RAM 中的所有密码对象归零并清除。(通过从 RAM 中清零和清除密码,我们减少了攻击者的机会窗口。即这减轻了冷启动攻击风险:https : //en.wikipedia.org/wiki/Cold_boot_attack

为了满足这一要求,我们最初遵循以下两个 SO 帖子中的建议将用户密码捕获为 CharArray 而不是字符串

//First collect the password from Edit Text as a []char
int pl = passwordEditText.length();
char[] password = new char[pl];
passwordEditText.getText().getChars(0, pl, password, 0);

//Now set the password on viewmodel
viewModel.setPassword(password) 
Run Code Online (Sandbox Code Playgroud)

获得密码后,我们使用它来调用第 3 方网络服务库,该库获取数据以显示在屏幕上。

视图模型伪代码:

public DataObject getData(char[] password){
     return this.webService.getData(password);
}
Run Code Online (Sandbox Code Playgroud)

当用户完成我们的应用程序时,我们调用以下方法将密码归零和清除

视图模型伪代码:

public zeroPassword(){
    Arrays.fill(this.password, 0);
    this.password = null; …
Run Code Online (Sandbox Code Playgroud)

memory security android

5
推荐指数
1
解决办法
254
查看次数

使用System.console()读取密码

java.io.Console类的javadoc中有一个安全说明:

安全说明:如果应用程序需要读取密码或其他安全数据,则应使用readPassword()或readPassword(String,Object ...)并在处理后手动将返回的字符数组归零,以最大限度地缩短内存中敏感数据的生命周期.

 Console cons;
 char[] passwd;
 if ((cons = System.console()) != null &&
     (passwd = cons.readPassword("[%s]", "Password:")) != null) {
     ...
     java.util.Arrays.fill(passwd, ' ');
 }
Run Code Online (Sandbox Code Playgroud)

我不明白为什么你需要这么激烈的措施?当读取密码的方法弹出堆栈时,passwd局部变量引用的数组对象将有资格进行垃圾回收.没有人(甚至是攻击者)可以获得对该数组的引用,假设数组没有转义方法范围.

那么为什么你需要修改数组(删除密码),当你知道一旦方法弹出堆栈就有资格获得GC?他们说:

最小化内存中敏感数据的生命周期

但对我来说,这种编程风格似乎相当......绝望.

java

4
推荐指数
2
解决办法
669
查看次数

如何将文本字段和密码字段与字符串值进行比较?

这是我使用 JDBC 连接的登录表单的代码,代码没有错误,但是当我运行它时,它总是转到 else 语句

    Connection con;
    Statement st;
    ResultSet rs;
    try{
      Class.forName("java.sql.Driver");
      con=DriverManager.getConnection   ("jdbc:mysql://localhost/database","root","password");
      st=con.createStatement();
      rs=st.executeQuery("select * from users;");
      while(rs.next()){
                String userID=rs.getString("userID");
                String password=rs.getString("password");

                if(userID.equals(txtuserID.getText())
                    && (password.equals(txtpassword.getPassword())) {
                // ***HERE IS MY PROBLEM I WANT TO CHECK IF WHATS IN THE 
                // TEXT FIELD OR PASSWORD FIELD IS THE SAME FROM MySQL***
                    JOptionPane.showMessageDialog(null,"you have logged in");
                    new MainForm().setVisible(true);
                } else {
                    JOptionPane.showMessageDialog(null,"Incorrect username and password");
                }
     }
  } catch(Exception e) {
     JOptionPane.showMessageDialog(null,"Error in Connectivity: " +e.getMessage());
  }  
Run Code Online (Sandbox Code Playgroud)

java mysql jdbc jtextfield jpasswordfield

3
推荐指数
1
解决办法
7064
查看次数

如何避免在需要字符串的第三方库中使用字符串作为密码或秘密?

我正在开发一个 Java 服务,该服务记录了一个安全错误,涉及存储在 Java String 对象中的秘密。

令人担忧的是,一旦密码存储在 a 中String,它就会保留在字符串池中,直到被垃圾收集,并且可能会以明文形式显示在转储中。

我理解Java的String类是不可变的,最好将秘密或密码存储在可变的类中,这样在使用后可以尽快从内存中删除。

参考

然而,我发现在使用第三方库时这是不切实际的,因为他们中的许多人都希望将请求中的密码或秘密作为 String 对象传递,无论我多么安全,在我的代码中,最终都会将数组转换char[]String,这让我们回到了最初的问题,不是吗?

那么,是否有办法将 achar[]或转换StringBuffer为 a String,而不回到原来的问题?

编辑:正如这个问题和其他类似问题中的评论所指出的,许多人认为这不是真正的问题,因为如果您不拥有应用程序中的所有代码(即不拥有),则没有简单的方法可以避免此问题不要将秘密传递给任何第三方库)。鉴于此,也许问题就变成了

我该如何反驳该错误?Oracle/Owasp 或任何说“无法解决的问题”的人是否有可靠的参考资料?

java

3
推荐指数
1
解决办法
157
查看次数