在java中,如何清除每个方法中的字节[]数组以保护值免受内存转储?
Posted
技术标签:
【中文标题】在java中,如何清除每个方法中的字节[]数组以保护值免受内存转储?【英文标题】:In java, how to clear byte[] array inside every method to protect the value from memory dump? 【发布时间】:2018-05-21 07:51:19 【问题描述】:在java中,
如果我在下面运行代码,pwd 值存在于整个内存中,因为字节数组值被复制到摘要方法,该方法也将值复制到其他一些方法。
import java.security.MessageDigest
byte[] pwd = "some_pwd".getBytes();
MessageDigest md = MessageDigest.getInstance("SHA");
for (int i = 0; i < 100; i++)
byte[] hash = md.digest(pwd);
内存转储软件显示我的客户不喜欢的密码值。
我检查了 byte[] 是按值从一个方法复制到另一个方法。
有没有办法保护重要的字节数组值?
【问题讨论】:
没有。您的代码确实处理了密码值(甚至只是散列它),因此它必须出现在程序 RAM 中。您唯一的选择是使保存密码的变量尽可能短(限制其范围)。 想一想,即使您可以将数组作为引用传递,如果您在使用此数组时转储内存,您将能够看到该值(不经常,但仍然至少1次) 【参考方案1】:密码文本最好不要作为字符串传递,但我们假设这是一个示例:
然后确保字节不会出现在测试字符串中。
byte[] pwd = "rnld^ovc".getBytes(StandardCharsets.UTF_8); // "some_pwd"
for (int i = 0; i < pwd.length; ++i)
pwd[i]++;
然后解决办法:
MessageDigest md = MessageDigest.getInstance("SHA");
for (int i = 0; i < 100; i++)
//byte[] hash = md.digest(pwd);
for (byte b : pwd)
md.update(b - 1); // Maybe -1 if the string was the real password
byte[] hash = md.digest();
Arrays.fill(pwd, (byte)0);
现在 MessageDigest 无法在调用摘要时维护数组的副本。
如果您甚至不想拥有 pwd 数组,则只需从密码字段中一次获取一个字符/字节。
【讨论】:
我想你忘了b -1
,否则你计算一个不同值的哈希
嗯,我不知道,我仍然不是 100% 满意 :) 但我认为这是你能做的最好的......
@JohnnyAW 我的意思是字符串包含廉价的 -1 加密,因此内存转储不会显示它,并且 pwd 包含真实密码;但除此之外 - 确实需要 1。
具有讽刺意味的是,最终的实际密码可能是“秘密”或“12345678”。
好一个,让 123456 尽可能安全:)以上是关于在java中,如何清除每个方法中的字节[]数组以保护值免受内存转储?的主要内容,如果未能解决你的问题,请参考以下文章
JAVA里String数组在内存分配中分配的空间每个占几个字节?