Neil 如此坚决不使用 MD5 的原因(顺便说一句,他是对的)是因为 MD5 容易受到攻击。这意味着如果攻击者找到哈希输出,则可以恢复密码。由于散列密码通常是为了在找到散列时不会显示原像(即密码),因此强烈(非常强烈)建议您不要使用 MD5。 (事实上,如果您在做生意并且使用 MD5 作为密码,那么请尽情享受疏忽诉讼。[不是法律建议]) Neil 推荐了一些好的哈希算法。 (为什么 MD5 易受攻击的细节远远超出了这个问题的范围。)
好的。您的问题是如何将多个事物组合在一起。
为了将多个事物散列在一起,您通常只需将它们连接起来,或者只是按顺序散列它们而不调用“digest()”。 (顺便说一句,顺序确实很重要。)在您的情况下,由于您在散列函数上有一个包装器,因此您只需在散列之前将字符串连接在一起。
String username = "myName";
String realm = "Narnia";
String password = "secret";
String hash = GenHash(username + realm + password);
在其他所有人的情况下,他们可能正在使用标准的 Java MessageDigest,因此他们会多次调用摘要……在将字符串转换为字节数组之后。 (请注意,在将字符串转换为字节数组时,您需要指定编码以确保始终以相同的方式完成,否则您的哈希函数可能会在不同的机器上返回不同的结果。)
byte[] usernameBytes; //Set equal to perhaps UTF32 encoding of the string
byte[] realmBytes; //Set equal to perhaps UTF32 encoding of the string
byte[] passwordBytes; //Set equal to perhaps UTF32 encoding of the string
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(usernameBytes); //Updates digest with these bytes
md.update(realmBytes); //Updates digest with these bytes
md.update(passwordBytes); //Updates digest with these bytes
byte[] hashResult = md.digest(); //Outputs result
//Insert code to convert the byte array to an outputtable form (or perhaps you're writing to a binary file)
但请记住:使用字符串会带来安全漏洞!
字符串永远不应该用于密码,因为字符串值不能保证被删除(因为它们驻留在堆上,因此在垃圾收集器可能到达时被“删除”,并且被“删除”我的意思是解除分配,而不是删除)。获得内存转储访问权限的攻击者可以读取密码。 (诚然,如果攻击者获得内存转储,您会遇到其他问题,但不要让情况变得更糟。)
最好将 char[] 用于所有密码或其他非常敏感的文本值。因此,您将创建一个大小为 (username.length() + realm.length() + password.length()) 的新字符数组,然后遍历每个字符串并将每个字符添加到新数组中......然后散列...然后您将擦除不再使用的所有敏感文本值(通过迭代每个数组并将每个元素设置为等于 (char)0)。
同样,您不能手动删除或擦除字符串,但可以手动擦除 char 或 char[]。
Why is char[] preferred over String for passwords?
当您使用它时,请查找密码或哈希加盐。它可能对您正在做的事情有用。