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