带有Java字符串的copymethod()

带有Java字符串的copymethod(),java,Java,我需要将不安全类的copymethod()用于字符串,我遇到了链接,在这里我找到了以下示例- String password = new String("l00k@myHor$e"); String fake = new String(password.replaceAll(".", "?")); System.out.println(password); // l00k@myHor$e System.out.println(fake); // ???????????? getUnsafe().

我需要将不安全类的copymethod()用于字符串,我遇到了链接,在这里我找到了以下示例-

String password = new String("l00k@myHor$e");
String fake = new String(password.replaceAll(".", "?"));
System.out.println(password); // l00k@myHor$e
System.out.println(fake); // ????????????
getUnsafe().copyMemory(
          fake, 0L, null, toAddress(password), sizeOf(password));

System.out.println(password); // ????????????
System.out.println(fake); // ????????????

static long toAddress(Object obj) {
    Object[] array = new Object[] {obj};
    long baseOffset = getUnsafe().arrayBaseOffset(Object[].class);
    return normalize(getUnsafe().getInt(array, baseOffset));
}

private static long normalize(int value) {
    if(value >= 0) return value;
    return (~0L >>> 32) & value;
}

我试过这个例子,但我得到了IllegalArgumentException。任何人都可以帮助这个例子工作。

我的建议:不要这样做

如果需要擦除字符串,可以使用反射来“安全地”清除字符串对象的私有
chars
数组,并用NUL字符填充它。当然,您需要确保正在擦除的字符串没有与其他代码共享;e、 g.它没有被拘留

您正在复制的代码看起来已损坏。首先,它似乎假设引用适合
int
。。。对于64位JVM来说,情况并非如此。我不相信那个密码。我甚至不想去修它。这完全是错误的做法

“不安全”只能由真正、真正知道自己在做什么的人使用。复制别人的代码不能代替知识

在这种情况下,我不认为原始代码正确地擦除了字符。事实上,我认为它仅仅是拆下
字符串
对象,将包含超级机密密码的
字符[]
保存在堆中。这篇博文实际上暗示了这一点


事实上,几乎不可能保证您已经删除了一个字符串。即使您成功地删除了包含字符的
char[]
,也无法确定这是数据的唯一副本。例如,如果字符串已被GC重新定位,则在原始位置的内存中仍可能存在字符的旧副本。字符最终将被覆盖,但无法保证何时会发生

可能您能做的最好的方法是使用JNI/JNA(或
Unsafe
)来分配一些堆外资源(GC不会重新定位这些资源),并在释放之前用零对其进行重写。显然,你不能用字符串来做这件事

即使这样。。。分页设备上可能有一些包含字符的旧页。或者有足够权限的人可以设置断点并从内存中读取秘密


我的建议:只需确保>>平台请提供stacktrace