【发布时间】:2021-10-12 12:32:10
【问题描述】:
我在 PHP 中使用这段代码来加密密码:
return sha1("kD0a1".md5("xA4".$password)."f4A");
有人知道在 Android 中使用的有效替代品吗?我为 MD5 和 SHA1 尝试了不同的函数,但在 Java 中它总是生成与 PHP 不同的 HASH。
例如如下:
public static String passwordHash(String password) {
return sha1("kD0a1"+md5("xA4"+password)+"f4A");
}
public static String md5(String s) {
try {
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static String sha1(String clearString) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
messageDigest.update(clearString.getBytes("UTF-8"));
byte[] bytes = messageDigest.digest();
StringBuilder buffer = new StringBuilder();
for (byte b : bytes) {
buffer.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return buffer.toString();
}
catch (Exception ignored) {
ignored.printStackTrace();
return null;
}
}
但是,PHP 和 Java 会返回一个不同的 HASH 字符串给我。
PASS: test
PHP: 17bf2c08f4b9447cf8316736e13833316d3edc23
JAVA: 8434696e252b89af0db033eb255c88a91a42ce14
但是,例如,如果我输入“passTest”,它将正确生成哈希
PASS: passTest
PHP: db4aedf1d4072b7b645996394aa74743f14eeb7a
JAVA: db4aedf1d4072b7b645996394aa74743f14eeb7a
而“passwordTest”又错了。
PASS: passwordTest
PHP: 1ad47c24d556187f1de5db66ff623bbe08a27f33
JAVA: 0f058b3aea48e69c028a7ee2693a98d6074b10a8
我无法解释它有时有效,有时无效,同时它只是更改密码的字符串。
您认为编码或其他方面可能存在问题吗?我以为是 TextView 做的,但即使我在 TextView 之外输入一个字符串,它的行为也是一样的。
提前感谢您的任何建议。
我要补充一点,我正在 SDK 31 上进行测试
M.
【问题讨论】:
-
确保在调用
getBytes时使用相同的编码,例如getBytes("UTF-8");并在 PHP 中使用相同的字符编码。你不是用 MD5 做的 -
“我在 PHP 中使用这段代码来加密密码”——它不加密密码。它使用不安全的哈希函数使用固定的盐对其进行两次哈希处理。 “我为 MD5 和 SHA1 尝试了不同的函数,但在 Java 中它总是生成与 PHP 不同的 HASH”——也许你应该一次只看一个。首先让你的 MD5 哈希匹配,没有盐。然后,将盐添加到您的 MD5 哈希中。然后,获取一个简单字符串的 SHA-1 哈希匹配。然后,为您的盐渍 MD5 输出获取您的 SHA-1 哈希匹配。以此类推。
-
然后然后使用正确的密码散列算法。
-
但是,正如 luk2302 所建议的那样,研究适当的密码散列算法(由安全专家创建的算法(scrypt、bcrypt、Argon2 等)并使用其中一种算法)可能会更好。跨度>
-
是的,你说得对,我忘了。对于 MD5,我将“md.digest()”替换为“md.digest (md5.getBytes("UTF-8"))”,现在它可以正常工作了。到目前为止,所有测试都通过了 100%,所以希望一切都会好起来的。再次感谢您的帮助。