Security <;h:inputSecret/>;安全性:有没有一种方法可以直接引用char[]而不是字符串?

Security <;h:inputSecret/>;安全性:有没有一种方法可以直接引用char[]而不是字符串?,security,jsf,Security,Jsf,序言:这可能是一个巨大的noob错误,我团队中的所有开发人员在java101上都有点模糊,所以如果我们什么都不担心,请告诉我。[具体而言,担心permgen中缓存的字符串文字] 我们有一个简单的登录页面,基本上如下所示: //支持Bean“LoginBean” //JSF 谢谢你的帮助,如果这是一个双重职位,请随意打我,我似乎找不到它,但它似乎是一个核心问题 这里我关心的是,传递的字符串文字可能会被缓存,并打开潜在的安全漏洞 你的担心只是部分有效。字符串文字是在Java类文件中实际作为文字出现的

序言:这可能是一个巨大的noob错误,我团队中的所有开发人员在java101上都有点模糊,所以如果我们什么都不担心,请告诉我。[具体而言,担心permgen中缓存的字符串文字]

我们有一个简单的登录页面,基本上如下所示: //支持Bean“LoginBean”

//JSF

谢谢你的帮助,如果这是一个双重职位,请随意打我,我似乎找不到它,但它似乎是一个核心问题

这里我关心的是,传递的字符串文字可能会被缓存,并打开潜在的安全漏洞

你的担心只是部分有效。字符串文字是在Java类文件中实际作为文字出现的文字。用户提供的密码不是字符串文字;相反,它是一个字符串对象,除非调用
String.intern()
,否则它不会被放入永久生成中

现在假设您没有犯调用
String.intern()
的愚蠢行为,那么应该解决内存中存在密码的另一个问题。这已经发生了(由于垃圾收集器执行对象的复制),JSF生命周期使得这不可能发生(因为需要为输入值构造字符串对象)。我编写了以下代码,以允许托管bean通过将字符串转换为char[]数组(反之亦然)将密码存储为字符数组,但如果您意识到
String
对象可能在内存中存在一段时间,则它仅用于合规性检查:

@FacesConverter("Char[]Converter")
public class CharArrayConverter implements Converter
{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String newValue)
    {
        if(newValue == null)
        {
            return newValue;
        }
        return newValue.toCharArray();
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        if(value == null)
        {
            return null;
        }
        char[] inputValue;
        try
        {
            inputValue = (char[]) value;
        }
        catch(ClassCastException ccex)
        {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Object was not present in the desired format", null);
            throw new ConverterException(message);
        }
        return new String(inputValue);
    }

}
转换器在Facelet中的用途如下:

...
<p>
    <h:outputLabel for="password" value="#{msg['Signup.password.label']}" />
    <h:inputSecret id="password" value="#{userManager.signupRequest.password}" converter="Char[]Converter" />
</p>
...
。。。

...
感谢您快速、周密的回复。为了安全起见,转换器似乎是一个很好的解决方案,它可以最大限度地降低风险并符合标准。谢谢你提供的信息。回答得好。然而,您编写的转换器似乎有点无用,因为数据仍将存在于某个地方。还是我遗漏了什么?@Ced,是的,答案中暗示了这一点。如果有人绝对需要管理char[]类型的类成员或变量中的密码,可能是出于政治原因(绕过静态代码分析标志)而不是技术原因,那么JSF转换器只会转移关注点。就Java web应用而言,考虑到该平台的内存管理功能如何阻止开发人员从内存中清除机密,我们无能为力。基于此讨论,我开始了一个关于一种有趣方法的新问题。。。
String username;
char[] password;
@FacesConverter("Char[]Converter")
public class CharArrayConverter implements Converter
{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String newValue)
    {
        if(newValue == null)
        {
            return newValue;
        }
        return newValue.toCharArray();
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        if(value == null)
        {
            return null;
        }
        char[] inputValue;
        try
        {
            inputValue = (char[]) value;
        }
        catch(ClassCastException ccex)
        {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Object was not present in the desired format", null);
            throw new ConverterException(message);
        }
        return new String(inputValue);
    }

}
...
<p>
    <h:outputLabel for="password" value="#{msg['Signup.password.label']}" />
    <h:inputSecret id="password" value="#{userManager.signupRequest.password}" converter="Char[]Converter" />
</p>
...