我正在传递敏感信息(在我的应用和后端之间),就像字符串格式的密码一样。 后来我意识到密码可以从堆内存转储中轻松读取,因为它以文本格式存储。
String password = "super_password";
所以我决定使用Char数组,
Char[] passChar = password.toCharArray();
但我担心仍然可以逐字符地从内存转储中读取密码。然后我想到了使用字节数组。
byte[] passByte = password.getBytes();
我的问题:使用字节数组传递密码等敏感信息是否安全? 或者任何人都可以推荐任何安全的东西吗?
答案 0 :(得分:1)
可能是您可以通过MD5或其他加密来加密密码。
package test.md5;
import java.security.MessageDigest;
public class MD5Util {
public final static String MD5(String s) {
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
try {
byte[] btInput = s.getBytes();
// get MD5 MessageDigest obj
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// update
mdInst.update(btInput);
// get encryption string
byte[] md = mdInst.digest();
// change to hexadecimal
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
System.out.println(MD5Util.MD5("20121221"));
System.out.println(MD5Util.MD5("encrypt"));
}
}
答案 1 :(得分:1)
Java中面向密码的API使用char[]
。例如,Console
和JPasswordField
会从密码输入中返回字符数组,PBEKey
和KeyStore
需要char[]
来进行基于密码的加密。
byte[]
和char[]
之间的转换会在堆中创建更多敏感数据副本,并且可能难以确保字符编码器从其内部缓冲区中删除所有密码数据。
使用char[]
存储密码,并在不再需要密码时使用write '\0'
to the array。
答案 2 :(得分:0)
字符只是字符的多字节表示,因此内存转储会产生几乎相同的结果。您应该考虑加密存储密码:如此stackoverflow答案:Encrypt Password in Configuration Files? (Java)
答案 3 :(得分:0)
我假设这个问题主要涉及将密码从一个主机上的一个进程转移到另一个主机上的另一个进程,但也包括将密码读入特定变量。
分配问题不仅限于将密码分配给String实例,该实例遇到其他SF答案(例如this)中详述的问题。我想补充一点,你不是在全局上下文中使用char或byte数组,而是在方法上下文中本地使用,这样一旦退出方法使其可用于GC,它就会快速超出范围。如果变量在年轻代中,那么一旦它超出范围,就需要多个GC循环来清除它。加上char / byte []是可变的,因此它也可以被清除。但是,仍然有机会从堆转储中恢复密码,它与此次重合。
简而言之: