我知道有几个这样的问题,但我尝试了在stackoverflow上找到的每一个解决方案,仍然没有得到预期的结果。
我试图用Java和PHP将一个字符串转换为sha1,但我得到了不同的结果。字符串是随机生成的。我检查了两端的字符串,它们是相同的(甚至尝试了在线比较工具)。
这是我在另一个应用程序中使用的相同代码,它在那里工作,但在这种情况下不工作。
我试图用sha1散列的一个字符串是:UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==
Java结果:72c9bbe7eed0efe5e82ea9568136d8f52347259e
PHP结果:f720d73d18a7bb9cf36808af17ce40621ebfb405
Java代码
public static String sha1(String toHash)
{
String hash = null;
try
{
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] bytes = toHash.getBytes("ASCII"); //I tried UTF-8, ISO-8859-1...
digest.update(bytes, 0, bytes.length);
bytes = digest.digest();
StringBuilder sb = new StringBuilder();
for(byte b : bytes)
{
sb.append(String.format("%02X", b));
}
hash = sb.toString();
}
catch(NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
}
return hash.toLowerCase(Locale.ENGLISH);
}
PHP代码
sha1("UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==");
如有任何帮助,将不胜感激
更新
在Java&PHP我正在做以下事情:
Java
String toHash = "qwerty";
String hash = sha1(toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e
toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b
PHP
$toHash = "qwerty";
sha1($toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e
sha1(base64_encode($toHash)); //Prints: 278aa0e8dde2af58a4eed613467da219a35c5278
我想Base64编码对字符串的作用与PHP和Java不同,有什么想法吗?
更新2
我本应该更清楚,对不起,我的意思是:
的输出Java
sha1(Base64.encodeToString("qwerty".getBytes("ASCII"), Base64.DEFAULT));
与的输出不同PHP
sha1(base64_encode("qwerty"));
更新3
尽管两个base64编码的字符串都是相等的CCD_ 4。
基本上:
- sha1("qwerty") == sha1("qwerty")
- Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT) == base64_encode("qwerty")
- sha1(Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT)) != sha1(base64_encode("qwerty"))
我已经在散列的字符串上删除了base64编码,但我仍然想知道我可以做些什么来使它工作。
编辑
您在encodeToString
方法中使用了两次toHash
变量,使第二行代码变得多余。
这个代码
String toHash = "qwerty";
String hash = sha1(toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e
toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b
相当于这个代码
String toHash = "qwerty";
toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b
所以本质上在java中你是
- 获取"qwerty"的Base64
- 获得该结果的sha1
当使用PHP时,您的是
- 获取"qwerty"的sha1
- 基于该结果获取Base64
我想你打错了
三年多后,我遇到了同样的问题,但这次我解决了问题。以下是任何偶然发现这个问题的人的解决方案:
我使用的是:
sha1("qwerty") == sha1("qwerty")
Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT) == base64_encode("qwerty")
sha1(Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT)) != sha1(base64_encode("qwerty"))
这个问题是Base64.DEFAULT
,Base64的默认行为包装字符串(将'n
添加到字符串中)。为了获得与PHP方法相同的结果,您应该使用Base64.NO_WRAP
:
sha1("qwerty") == sha1("qwerty")
Base64.encodeToString("qwerty".getBytes(), Base64.NO_WRAP) == base64_encode("qwerty")
sha1(Base64.encodeToString("qwerty".getBytes(), Base64.NO_WRAP)) == sha1(base64_encode("qwerty"))
在我做了这个更改之后,它开始工作