【问题标题】:How are Strings in StringPool insecure?StringPool 中的字符串如何不安全?
【发布时间】:2015-03-04 05:06:23
【问题描述】:

建议将密码存储在 char[] 而不是 String 中,因为 Strings 存储在 StringPool 中。 Read more here

根据this question StringPool 中的字符串不能直接使用。 要在 Stringpool 中获取字符串,我们需要一个密码字典来在 StringPool 中检查它们。如果我们有密码字典,我们不需要担心 StringPool,我们可以直接在密码字段上尝试。

那么,为什么我们不应该使用“字符串”作为密码的数据类型呢?

编辑:

得到的答案是:我们可以访问内存转储并访问字符串池中的字符串。

跟进问题:

  • 如何访问内存转储?
  • 可以阻止访问吗?
  • 如果阻止访问内存转储,使用字符串作为密码类型是否安全?

【问题讨论】:

  • 感谢@Ruchira 让我知道重复。但是,我脑海中的问题仍然不清楚。我已修改问题,请删除重复标记
  • 现在你的答案在这里。stackoverflow.com/questions/8881291/…
  • 酷。我现在的问题是“如果另一个进程可以转储内存”,进程如何转储包含字符串池的内存?并对现有字符串进行相同的分析?
  • stackoverflow.com/questions/12018675/… 这回答了一点,但答案没有解释清楚。另外,我想使用 Java 代码本身,而不是任何外部工具
  • “StringPool”是什么意思? StringPool 是 Java 编译器从源代码中保存常量的地方。因此,如果您在 StringPool 中有密码,那么这意味着您的密码已硬编码在 java 源文件中。你不应该这样做既不作为字符串也不作为字符数组。

标签: java string security passwords jvm


【解决方案1】:

String 在 java 中是不可变的,存储在字符串池中。 一旦它被创建,它就会一直留在池中,直到没有垃圾收集,所以即使我们完成了密码,它也可以在内存中使用更长的时间,并且没有办法避免它。这是一个安全风险,因为任何有权访问内存转储的人都可以找到明文形式的密码。

如果我们使用 char 数组来存储密码,我们可以在完成后将其设置为空白。所以我们可以控制它在内存中的可用时间,从而避免了 String 的安全威胁

【讨论】:

  • 能否提供访问内存转储的详细信息?
  • 有很多方法可以获得堆转储,从简单的工具(如 jmap)到更花哨的工具(如 JVisualVM)甚至是商业工具(如 JProfiler)。但是,正确解释这些转储可能会很棘手,因此您可能希望准确地发布您正在寻找的内容。
  • 我希望从 Stringpool 获取字符串。你能分享一些指针/一步一步的过程吗?
  • //创建字符串对象
    String s1=new String("Test");
    //字符串字面量
    String s2="Test";
    System.out.println(s1==s2);//false
    //true >因为intern方法从StringPool访问字符串
    System.out.println(s1.intern()= =s2);//true
    System.out.println(System.identityHashCode(s1));//359925(堆地址)
    System.out.println(System.identityHashCode(s1.intern ()));//9473797(字符串池地址)
    System.out.println(System.identityHashCode(s2));//9473797
    System.out.println(System.identityHashCode(s2) .intern()));//9473797
  • 这没有帮助。就像我要使用蛮力来了解字符串池中是否存在字符串一样,我无论如何都可以在字段本身上使用蛮力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多