使用Apache HTTP Client而不将凭据作为String传递?

时间:2017-03-17 15:59:08

标签: java security passwords httpclient apache-httpclient-4.x

在对我们的Swing应用程序进行审核之后,我们的用户的一些密码似乎在他们登录或甚至退出后都会留在内存中。

其中一个原因似乎是Apache HttpClient的UsernamePasswordCredentials将密码存储为final String,阻止以编程方式将其从内存中删除(请参阅Why is char[] preferred over String for passwords?)。

但是,由于它实现的Credentials接口有String getPassword()方法,因此似乎无法避免在某些时候转换为String

在这种情况下,是否有其他方法可以避免将密码作为String传递?

我们正在使用HttpClient 4.0.3,但在最近的版本中似乎没有改变。

2 个答案:

答案 0 :(得分:0)

Apache表示不推荐使用密码String初始化UsernamePasswordCredentials

  

UsernamePasswordCredentials(String usernamePassword)
  的已过时。
  (4.5)将替换为String,char [] in 5.0

     

UsernamePasswordCredentials(String userName, String password)
  带有用户名和密码参数的构造函数。

https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/auth/UsernamePasswordCredentials.html

您使用的是最新版本的库吗?如果是这样,他们不会将密码存储为String而是char []。

答案 1 :(得分:0)

最后,我实施了解决方法proposed by Edd in the comments of his answer

char[] password = …
final Credentials credentials = new UsernamePasswordCredentials(username, null) {
    @Override
    public String getPassword() {
        // AKCTAT-3791: this helps the GC to clear the String from the memory, as it will be used and dismissed immediately
        // Unfortunately Apache HTTP Client does not allow to pass the byte[] directly
        return new String(password);
    }
};
httpClient.getCredentialsProvider().setCredentials(ANY_AUTHSCOPE, (Credentials) auth.getCredentials());
// ... (do stuff with httpClient)
Arrays.fill(password, '\0');

GC看起来很快就会从内存中删除它,但它仍然只是一种无法保证的解决方法。