Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
你能用PHP得到同样的JavaSHA-1吗?_Java_Php_Hash_Passwords_Sha - Fatal编程技术网

你能用PHP得到同样的JavaSHA-1吗?

你能用PHP得到同样的JavaSHA-1吗?,java,php,hash,passwords,sha,Java,Php,Hash,Passwords,Sha,我发现自己需要将网站平台从Java更改为PHP,但我想保留所有用户的密码 在将哈希值作为密码写入网站之前,我让此代码进行密码哈希: MessageDigest md = null; md = MessageDigest.getInstance("SHA"); md.update(plaintext.getBytes("UTF-8")); byte raw[] = md.digest(); hash = new Base64().encodeToString(raw).replaceAll("\n

我发现自己需要将网站平台从Java更改为PHP,但我想保留所有用户的密码

在将哈希值作为密码写入网站之前,我让此代码进行密码哈希:

MessageDigest md = null;
md = MessageDigest.getInstance("SHA");
md.update(plaintext.getBytes("UTF-8"));
byte raw[] = md.digest();
hash = new Base64().encodeToString(raw).replaceAll("\n", "").replaceAll("\r", "");
我认为Java代码对密码进行了SHA-1散列,但就在这之前,它被字节编码为UTF-8,之后是Base64编码

我希望PHP代码也能这样做,即为Java中相同的密码返回相同的散列值,只是似乎执行SHA-1散列的PHP代码不会返回相同的SHA(-1,我想不是Base64编码的?)值与哈希值的JavaBase64解码值相比……这可能与我在PHP中的密码不是首先进行UTF-8字节编码(我在PHP中如何做到这一点)有关吗

p.s.

另一件奇怪的事…我在Java中的密码都是28个字符长(通常是这样的
rnwn4zTNgH30l4pP8V05lRVGmF4=
)…但是这些密码哈希的
Base64().decode(hash)
值是10个字符长(例如
[B@14e1f2b

我认为Base64在每3个字符中增加了1个字符(28或27个,不包括padding=charter,比这10个字符大三分之一),那么我的解码调用是否有可能出错


最重要的是,PHP中的SHA-1密码散列值有40个字符长(在UTF-8 mysql数据库中),就像这样
dd94709528bb1c83d08f3088d4043f4742891f4f

[B@14e1f2b
绝对不是散列。它是从
字节[]
字符串的隐式转换的结果

看起来你是这样做的:

String decodedHash = Base64().decode(hash); // Produces [B@14e1f2b
但是,哈希的正确表示形式是字节数组:

byte[] decodedHash = Base64().decode(hash); 

我通常使用Java计算与PHP sha1()完全相同的SHA-1哈希函数如下。关键是toHexString用于以可打印的方式显示原始字节。如果使用PHP函数并希望获得与复杂过程相同的结果,则需要在PHP中使用参数$raw_output to true来获得原始字节并应用Base64

/**
*计算字符串参数的SHA-1哈希
*
*@param arg要编码的UTF-8字符串
*@以字符串形式返回sha1哈希。
*/
公共静态字符串计算HA1OFSTRING(字符串参数){
试一试{
返回计算ha1ofbytearray(arg.getBytes((“UTF-8”);
}捕获(不支持DencodingException ex){
抛出新的不支持操作异常(ex);
}
}
私有静态字符串计算ha1ofbytearray(字节[]arg){
试一试{
MessageDigest md=MessageDigest.getInstance(“SHA-1”);
md.update(arg);
字节[]res=md.digest();
返回到hextstring(res);
}捕获(nosuchalgorithmex异常){
抛出新的不支持操作异常(ex);
}
}
私有静态字符串到十六进制字符串(字节[]v){
StringBuilder sb=新StringBuilder(v.length*2);
对于(int i=0;i>>4)).追加(十六进制数字.charAt(b&0xF));
}
使某人返回字符串();
}
PHP()默认情况下将输出的每个字节编码为十六进制,但您可以通过将
true
作为第二个参数传递来获得原始输出:

$digest = sha1($password, true); // This returns the same string of bytes as md.digest()
然后将摘要传递给,您就完成了:

base64_encode(sha1($password, true));

这将返回与java代码完全相同的SHA-1哈希值。

您需要正确格式化代码。在每行前面放置四个空格或一个制表符。@Alberteddu:这可以通过选择代码并单击“{}”图标来完成。
[B@14e1f2b
不是
Base64()的值。解码(哈希)
,它是数组的常规字符串表示形式,形式为
[
+ArrayType+
@
+hashCode。您要做的是遍历数组,而不仅仅是简单地编写
System.out.println(array\u var);
PHP中的sha1函数返回一个十六进制数的字符串,而Java代码返回一个base64编码的字符串。非常感谢大家指出我的错误。但是,正确的字节[]到字符串转换会返回我在PHP中得到的40个字符吗?我为格式错误道歉(我也是一个非常讨厌的人)@Nubie:如果PHP生成一个十六进制值,您可以尝试将结果数组转换为十六进制字符串,并检查它们是否匹配。@axtavt有点挑剔,在
[B@13e1f2b
后面的部分实际上是一个散列,但显然不是Nubie想要的部分。它是toString()的输出方法,其主体是:
getClass().getName()+“@”+Integer.toHexString(hashCode());
base64_encode(sha1($password, true));