0

help me please with implementing semantic code from manual about SCRAM-SHA-1 authorization in XMPP server. So, we got:

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)

My PHP code:

$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);

Somewhere error (maybe ALL big error ;)) and I very need your help for correcting my code, maybe I am use wrong functions, or arguments in wrong positions? Because result - fail, server sends me that:

"The response provided by the client doesn't match the one we calculated."

PS: Sorry for my bad English ;)

scrowler
  • 24,273
  • 9
  • 60
  • 92

1 Answers1

1

First of all, it's very confusing to use $salt for the serverNonce and $ps for the salt.

But more importantly, you should take some care to keep track of whether the functions you use return binary data or hexadecimal encoded strings. hash_pbkdf2, sha1 and hash_hmac by default return hexadecimal encoded strings. You call pack('H*', ...) to decode them for the $cproof, but not when you calculate $ckey and $csign.

A much easier way is to compute binary data directly, by always passing $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);

Also, your hash_hmac calls were the wrong way around: first the data, then the key.

xnyhps
  • 3,306
  • 17
  • 21
  • Bro, I saw your comment at "http://stackoverflow.com/questions/29298346/xmpp-sasl-scram-sha1-authentication" and very want ask question directly to you, but not found where there is private messages, and you come here, thank you!)) Yes, salt - just my fast mistake when I making that demo code and it is I understand just after posting my message. So, ok - I will try all you recommends little bit later and then report here about result! – Andrey Samozhenkov Sep 23 '15 at 09:10
  • Can you help me with one more question, much easy then that? http://stackoverflow.com/questions/32728223/sasl-password-normalization – Andrey Samozhenkov Sep 23 '15 at 09:17
  • And something still wrong... Server First Message - is the full block [ cj02ZDQ0MmI1ZDllNTFhNzQwZjM2OWUzZGNlY2YzMTc4ZWMxMmIzOTg1YmJkNGE4ZTZmODE0YjQyMmFiNzY2NTczLHM9UVNYQ1IrUTZzZWs4YmY5MixpPTQwOTY= ] or base64_decoded inner string? And same question about initial message. And second question about final result - MY_SEND_TO_SERVER_FUNCTION(''.base64_encode($cfm).''); Right? Or I need to do somethnig more with result, before send it? – Andrey Samozhenkov Sep 23 '15 at 17:08
  • 1
    The Server First Message should be something of the form r=abcabcabc,s=QSXCR+Q6sek8bf92,i=4096. So it's not base64-encoded and without the XML. Your client final message looks correct. – xnyhps Sep 23 '15 at 19:28