Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.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中,如何从HttpServletRequest头提取密码而不生成String对象?_Java_Security_Servlets_Passwords_Http Headers - Fatal编程技术网

在Java中,如何从HttpServletRequest头提取密码而不生成String对象?

在Java中,如何从HttpServletRequest头提取密码而不生成String对象?,java,security,servlets,passwords,http-headers,Java,Security,Servlets,Passwords,Http Headers,处理敏感数据(=密码)的通用Java安全指南建议永远不要使用字符串对象来存储数据,而是使用字节或字符数组。我正试图在HttpServlet处理程序中应用此准则。特别是,我使用的是一种基本的类似身份验证的方法,其中凭据在头中传递(这是一个GET请求,因此没有正文) 我遇到的问题是,在不生成String对象的情况下,似乎不可能获取标题数据,这违反了get go的指导原则。我已经非常彻底地寻找了解决方案,但没有找到任何相关的讨论。有人对这个问题有什么见解吗 注意:这是通过HTTPS实现的,因此这里没有

处理敏感数据(=密码)的通用Java安全指南建议永远不要使用字符串对象来存储数据,而是使用字节或字符数组。我正试图在HttpServlet处理程序中应用此准则。特别是,我使用的是一种基本的类似身份验证的方法,其中凭据在头中传递(这是一个GET请求,因此没有正文)

我遇到的问题是,在不生成String对象的情况下,似乎不可能获取标题数据,这违反了get go的指导原则。我已经非常彻底地寻找了解决方案,但没有找到任何相关的讨论。有人对这个问题有什么见解吗


注意:这是通过HTTPS实现的,因此这里没有连接安全问题。

简单的答案是,除了字符串之外,您无法以任何其他形式获取参数。至少,不使用标准servlet API。但也有一些可能的“脱身”

  • 如果你准备变得非常丑陋,你实际上可以打破字符串对象的抽象,进入并覆盖字符。(如果您准备打破规则,字符串实际上是可变的。这是为数不多的可以证明这一点的情况之一。)

  • 为此,您的web容器的(比如)HttpServletRequest的实现中可能有一个非标准API扩展。如果没有,您可以获得源代码并添加一个。(假设您使用的是开源web容器。)


  • 话虽如此,IMO对Java安全性的“无条件”方法是错误的,或者至少在实现方面被高估了

    “无字符串”方法可以防止某些东西可能会在应用程序的地址空间中搜索,找到看起来像字符串的东西,并嗅出可能的密码。理论上,这可以通过以下方式实现:

    • 破坏JVM执行模型并查看原始内存的黑客行为
    • 附加Java调试器并遍历可访问对象
    • 使用“/dev/mem”或类似工具从外部读取进程内存
    • 访问硬盘上程序交换映像的剩余部分,或
    • 以某种方式使其核心转储并读取转储
    然而,除了第一个,所有这些都要求坏家伙已经破坏了系统的安全性。如果坏人这么做了,还有其他(可能更简单的)方法从你的程序中窃取密码。。。这是“无条件”方法无法阻止的

    如果您担心有黑客利用Java安全漏洞读取原始内存,那么该漏洞可能会被用于其他方面;e、 g.注入代码以改变代码处理密码的方式


    总之,“无条件”可以防止真正困难的黑客攻击,或者防止您的安全性已经被破坏的情况。依我看,这是不值得的努力。。。除非你被要求实现军事级安全。

    @smk:因为
    String
    s可以被拘留,这意味着它们在你使用完之后很长时间都会留在内存中。@smk字符串是不可变的。一旦你有了一个,它就会一直挂在内存中,直到它被垃圾回收(在你处理完之后很久)。使用
    字节[]
    ,一旦使用完毕,就可以覆盖内容以防止数据被读取。@CameronSkinner这与实习无关(尽管这会加剧问题)。即使堆空间中尚未被垃圾收集的字符串在内存中仍然是不可变的。也许这种担心在客户端机器上有一定的有效性,但在服务器机器上却没有,因为服务器机器上有很多更重要的秘密可以轻易地访问。请参阅#1,Java是否定义了可能发生的后果?假设内存中某处已经存在一个相等的字符串,例如哈希表中的一个键。在这种情况下,Java实现是否允许将两个字符串映射到同一个“文本备份存储”(抱歉,我不知道这里的确切Java术语)?如果是这样的话,通过明确清除HTTP数据包中的字符串,我实际上可能在我的应用程序中打开了一个恶意的DOS安全漏洞,它可以做到这一点。但实际上,只有在两个字符串上都调用
    String.intern()
    时,它才会这样做。另一种可能性是密码字符串与较大的字符串共享支持;e、 g.表示标题行的字符串。我认为这两种情况都不会有问题。实际上,还有另一种情况。这是较旧的JVM,
    String
    的实现在某些情况下会在不同的字符串之间共享
    char[]
    后备数组。字符串的实现在Java1.7.0_6中被重写以解决这个问题。(这是内存泄漏的来源!)