PHP 的 SCRAM-SHA-1 认证
SCRAM-SHA-1 auth by PHP
请帮助我在 XMPP 服务器中实现有关 SCRAM-SHA-1 授权的手册中的语义代码。所以,我们得到了:
clientFinalMessageBare = "c=biws,r=" .. serverNonce
saltedPassword = PBKDF2-SHA-1(normalizedPassword, salt, i)
clientKey = HMAC-SHA-1(saltedPassword, "Client Key")
storedKey = SHA-1(clientKey)
authMessage = initialMessage .. "," .. serverFirstMessage .. "," .. clientFinalMessageBare
clientSignature = HMAC-SHA-1(storedKey, authMessage)
clientProof = clientKey XOR clientSignature
clientFinalMessage = clientFinalMessageBare .. ",p=" .. base64(clientProof)
我的PHP代码:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter);
//hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $salt, $iter, 0, true); maybe like that???
$ckey = hash_hmac('sha1', $saltpass, 'Client Key');
$sckey = sha1($ckey);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $sckey, $authmsg);
$cproof = bin2hex(pack('H*',$ckey) ^ pack('H*',$csign));
$cfm = $cfmb.',p='.base64_encode($cproof);
某处错误(可能是所有大错误 ;)),我非常需要你的帮助来更正我的代码,也许我使用了错误的函数,或者参数在错误的位置?因为结果 - 失败,服务器向我发送:
"The response provided by the client doesn't match the one we calculated."
PS:抱歉我的英语不好 ;)
首先,对 serverNonce 使用 $salt
而对 salt 使用 $ps
是非常令人困惑的。
但更重要的是,您应该注意跟踪您使用的函数是 return 二进制数据还是十六进制编码字符串。 hash_pbkdf2
、sha1
和 hash_hmac
默认为 return 十六进制编码字符串。您调用 pack('H*', ...)
为 $cproof
解码它们,但当您计算 $ckey
和 $csign
.
时则不会
一种更简单的方法是直接计算二进制数据,方法是始终传递 $raw_data = TRUE
:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter, 0, TRUE);
$ckey = hash_hmac('sha1', 'Client Key', $saltpass, TRUE);
$sckey = sha1($ckey, TRUE);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $authmsg, $sckey, TRUE);
$cproof = $ckey ^ $csign;
$cfm = $cfmb.',p='.base64_encode($cproof);
此外,您的 hash_hmac
调用方式错误:首先是数据,然后是密钥。
请帮助我在 XMPP 服务器中实现有关 SCRAM-SHA-1 授权的手册中的语义代码。所以,我们得到了:
clientFinalMessageBare = "c=biws,r=" .. serverNonce
saltedPassword = PBKDF2-SHA-1(normalizedPassword, salt, i)
clientKey = HMAC-SHA-1(saltedPassword, "Client Key")
storedKey = SHA-1(clientKey)
authMessage = initialMessage .. "," .. serverFirstMessage .. "," .. clientFinalMessageBare
clientSignature = HMAC-SHA-1(storedKey, authMessage)
clientProof = clientKey XOR clientSignature
clientFinalMessage = clientFinalMessageBare .. ",p=" .. base64(clientProof)
我的PHP代码:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter);
//hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $salt, $iter, 0, true); maybe like that???
$ckey = hash_hmac('sha1', $saltpass, 'Client Key');
$sckey = sha1($ckey);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $sckey, $authmsg);
$cproof = bin2hex(pack('H*',$ckey) ^ pack('H*',$csign));
$cfm = $cfmb.',p='.base64_encode($cproof);
某处错误(可能是所有大错误 ;)),我非常需要你的帮助来更正我的代码,也许我使用了错误的函数,或者参数在错误的位置?因为结果 - 失败,服务器向我发送:
"The response provided by the client doesn't match the one we calculated."
PS:抱歉我的英语不好 ;)
首先,对 serverNonce 使用 $salt
而对 salt 使用 $ps
是非常令人困惑的。
但更重要的是,您应该注意跟踪您使用的函数是 return 二进制数据还是十六进制编码字符串。 hash_pbkdf2
、sha1
和 hash_hmac
默认为 return 十六进制编码字符串。您调用 pack('H*', ...)
为 $cproof
解码它们,但当您计算 $ckey
和 $csign
.
一种更简单的方法是直接计算二进制数据,方法是始终传递 $raw_data = TRUE
:
$cfmb = 'c=biws,r='.$salt;
$saltpass = hash_pbkdf2('sha1', 'IDoMdGuFE9S0', $ps, $iter, 0, TRUE);
$ckey = hash_hmac('sha1', 'Client Key', $saltpass, TRUE);
$sckey = sha1($ckey, TRUE);
$authmsg = $im.','.$chal.','.$cfmb;
$csign = hash_hmac('sha1', $authmsg, $sckey, TRUE);
$cproof = $ckey ^ $csign;
$cfm = $cfmb.',p='.base64_encode($cproof);
此外,您的 hash_hmac
调用方式错误:首先是数据,然后是密钥。