我有一个包含HTTP请求主体的byte[]
。在正文中,我想在登录整个正文之前删除密码信息。如果我首先将byte[]
转换为字符串,我可以删除密码信息,但据我所知,将密码转换为字符串从来都不是一个好主意(因为密码将存储在字符串池中,因此这是一个安全问题(。
byte[]
的内容类似于(但它可以更改(:body: [{"email":"email@email.com","password":"some_password",.....}]
那么,如何在不首先将"password":"some_password"
部分转换为字符串的情况下从byte[]中删除呢?
如果我首先将byte[]转换为字符串,我可以删除密码信息。
我不明白你为什么这么想。如果要删除密码信息,只需更新包含密码字符的byte[]
单元格即可。例如
for (int i = start_of_password; i < end_of_password; i++) {
bytes[i] = 'X';
}
如果你确实需要从byte[]
中提取密码,你可以将字符放入另一个byte[]
。。。使用后即可擦除。
。。。但据我所知,将密码转换为字符串从来都不是一个好主意(因为密码将存储在字符串池中,因此这是一个安全问题(。
当您从一些字节创建JavaString
(或通过调用new String(other_string)
(时,这不会将生成的字符串放入字符串池中。您刚刚创建的字符串是一个普通的堆对象。除非您的应用程序将引用保存在某个地方,否则它很快就有资格进行垃圾收集。
String
进入字符串池的情况只有两种:
String
对应于源代码或中的字符串文字(或"常量表达式"(时
当有东西在CCD_ 14对象上显式调用CCD_。
需要考虑的另一件事是,为什么内存中的长寿命String
可能被认为是一个安全问题。问题是,"坏人"有可能掌握密码。有几个潜在的场景:
如果有人能够破坏JVM并向其中注入错误代码(针对JVM或应用程序安全缺陷(,那么他们可能能够提取字符串。不过这真的很难实现。它需要大量的应用程序和运行它的框架的知识。事实上,从
byte[]
中提取密码同样容易。无论如何,解决这个问题的方法是让JVM保持最新,并审计代码库中可能导致JVM黑客攻击的公开安全问题。如果有人可以获得root访问权限,他们可以使用它读取任何进程的内存。在简单的情况下,他们可以获得整个过程的核心转储。但如果他们能做到这一点,他们也可以悄悄地修改你的应用程序或框架,以记录密码并过滤它们。解决方法是使您的系统安全性和程序达到标准。
如果有人可以对您的服务器进行物理访问,他们可以窃取dard驱动器,并从交换区域恢复JVM内存的部分副本。对此的补救措施是为服务器实现适当的物理安全。
现在所有这些攻击都是合理的,但在每种情况下都有一个简单的缓解。。。或者一种简单的方法来克服"字符串中没有密码"的预防措施。我建议在处理这一问题之前采取其他措施。
在解释代码时,字节数组包含关键字body、电子邮件和密码。因此,您可以检查关键字的字节是否在不同的字节数组样本之间没有变化,如果它们没有变化,则删除password关键字字节之后的所有内容。如果你在密码之后有另一个关键字,那么你只需删除所有直到这个关键字为止的内容。
下面是一个例子,它看起来是什么样子的:
import java.util.ArrayList;
public class MyClass {
public static void main(String args[]) {
byte a[] = "body: [{"email":"email@email.com","password":"some_password",.....}]".getBytes();
byte[] pass = {34,112,97,115,115,119,111,114,100,34,58,34}; //""password":"".getBytes();
byte[] end = {34,44}; //"",".getBytes();
ArrayList<Byte> arrList= new ArrayList<Byte>();
boolean foundPassword = false;
for(int i=0;i<a.length;i++){
if (a[i] == pass[0] && a[i+1] == pass[1] && a[i+2] == pass[2] && a[i+3] == pass[3] && a[i+4] == pass[4] && a[i+5] == pass[5] && a[i+6] == pass[6] && a[i+7] == pass[7] && a[i+8] == pass[8] && a[i+9] == pass[9] && a[i+10] == pass[10] && a[i+11] == pass[11]){
i = i+12;
foundPassword = true;
} else if (!foundPassword){
arrList.add(a[i]);
} else if (foundPassword && a[i] == end[0] && a[i+1] == end[1]){
arrList.add(new Integer(44).byteValue());
foundPassword = false;
i+2;
}
}
byte[] result = new byte[arrList.size()];
for(int i=0;i<arrList.size();i++)
result[i] = arrList.get(i);
System.out.println(new String(result));
}
}
输出:body: [{"email":"email@email.com",,.....}]