3 回答
TA贡献1993条经验 获得超5个赞
Oracle有一个GuardedString
实现。它与.NETSecureString
解决方案最接近。
安全的字符串实现,解决了与将密码保留为关联的问题
java.lang.String
。也就是说,任何表示为字符串的内容都将作为明文密码保存在内存中,并且至少保留到内存中直到被垃圾回收为止。所述
GuardedString
类通过以加密的形式存储在存储器中的字符减轻这个问题。加密密钥将是随机生成的密钥。
GuardedString
s将以其序列化形式使用已知的默认密钥进行加密。这是为了提供最低级别的保护,而不管运输情况如何。为了与远程连接器框架进行通信,建议部署启用SSL进行真正的加密。应用程序也可能希望继续存在
GuardedString
。对于Identity Manager,应将转换GuardedString
为,EncryptedData
以便可以使用Identity Manager的“管理加密”功能对其进行存储和管理。其他应用程序可能希望APIConfiguration
整体进行序列化。这些应用程序负责对APIConfiguration
Blob进行加密,以提供额外的安全性(除了所提供的基本默认密钥加密之外GuardedString
)。
TA贡献1848条经验 获得超2个赞
我修改了OWASP版本,以将char数组随机填充到内存中,以便静止时的char数组不与实际字符一起存储。
import java.security.SecureRandom;
import java.util.Arrays;
/**
* This is not a string but a CharSequence that can be cleared of its memory.
* Important for handling passwords. Represents text that should be kept
* confidential, such as by deleting it from computer memory when no longer
* needed or garbaged collected.
*/
public class SecureString implements CharSequence {
private final int[] chars;
private final int[] pad;
public SecureString(final CharSequence original) {
this(0, original.length(), original);
}
public SecureString(final int start, final int end, final CharSequence original) {
final int length = end - start;
pad = new int[length];
chars = new int[length];
scramble(start, length, original);
}
@Override
public char charAt(final int i) {
return (char) (pad[i] ^ chars[i]);
}
@Override
public int length() {
return chars.length;
}
@Override
public CharSequence subSequence(final int start, final int end) {
return new SecureString(start, end, this);
}
/**
* Convert array back to String but not using toString(). See toString() docs
* below.
*/
public String asString() {
final char[] value = new char[chars.length];
for (int i = 0; i < value.length; i++) {
value[i] = charAt(i);
}
return new String(value);
}
/**
* Manually clear the underlying array holding the characters
*/
public void clear() {
Arrays.fill(chars, '0');
Arrays.fill(pad, 0);
}
/**
* Protect against using this class in log statements.
* <p>
* {@inheritDoc}
*/
@Override
public String toString() {
return "Secure:XXXXX";
}
/**
* Called by garbage collector.
* <p>
* {@inheritDoc}
*/
@Override
public void finalize() throws Throwable {
clear();
super.finalize();
}
/**
* Randomly pad the characters to not store the real character in memory.
*
* @param start start of the {@code CharSequence}
* @param length length of the {@code CharSequence}
* @param characters the {@code CharSequence} to scramble
*/
private void scramble(final int start, final int length, final CharSequence characters) {
final SecureRandom random = new SecureRandom();
for (int i = start; i < length; i++) {
final char charAt = characters.charAt(i);
pad[i] = random.nextInt();
chars[i] = pad[i] ^ charAt;
}
}
}
添加回答
举报