Skip to content

Instantly share code, notes, and snippets.

@markokr
Created January 28, 2013 11:43
Check rfc5802 test vector correctness.
#! /usr/bin/env python
"""Check RFC5802 test vector.
"""
import hashlib
import hmac
import struct
def base64(s):
return s.encode('base64').strip()
def xor_bytes(s1, s2):
res = bytearray(s1)
for i in range(len(res)):
res[i] ^= ord(s2[i])
return str(res)
def hash_sha1(data):
return hashlib.sha1(data).digest()
def hmac_sha1(key, data):
return hmac.HMAC(key, data, hashlib.sha1).digest()
def hmac_sha1_iter(key, data, icount, blocknr=1):
# Single segment of PBKDF2-HMAC-SHA1.
blk = struct.pack(">L", blocknr)
u = hmac_sha1(key, data + blk)
res = bytearray(u)
i = 1
while i < icount:
u = bytearray(hmac_sha1(key, u))
for j in range(len(res)):
res[j] = res[j] ^ u[j]
i += 1
return str(res)
#
# Try to process test vectors from RFC5802
#
def sasltest():
# test hmac_sha1_iter() with test vector from RFC6070
pbkdf2_expect = '4b007901b765489abead49d926f721d065a429c1'.decode('hex')
if hmac_sha1_iter('password', 'salt', 4096) != pbkdf2_expect:
raise Exception("Buggy hmac_sha1_iter")
# messages from RFC5802
client_first = 'n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL'
client_first_bare = 'n=user,r=fyko+d2lbbFgONRv9qkxdawL'
server_first = 'r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096'
client_final = 'c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts='
client_final_without_proof = 'c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j'
server_final = 'v=rmF9pqV8S7suAoZWja4dJRkFsKQ='
# client & server proofs in RFC
expect_client_proof = 'v0X8v3Bz2T0CJGbJQyF0X+HI4Ts='
expect_server_proof = 'rmF9pqV8S7suAoZWja4dJRkFsKQ='
# hash password
psw = 'pencil'
salt = 'QSXCR+Q6sek8bf92'
salted_psw = hmac_sha1_iter(psw, salt, 4096)
client_key = hmac_sha1(salted_psw, "Client Key")
server_key = hmac_sha1(salted_psw, "Server Key")
stored_key = hash_sha1(client_key)
auth_msg = "%s,%s,%s" % (client_first_bare, server_first, client_final_without_proof)
sig = hmac_sha1(stored_key, auth_msg)
client_proof = base64(xor_bytes(client_key, sig))
server_proof = base64(hmac_sha1(server_key, auth_msg))
print "Client Proof: expect=%s got=%s" % (expect_client_proof, client_proof)
print "Server Proof: expect=%s got=%s" % (expect_server_proof, server_proof)
if __name__ == '__main__':
sasltest()
@xnyhps
Copy link

xnyhps commented Nov 20, 2014

I found this page while googling for SCRAM test vectors, but the code is wrong, so beware. The salt still needs to be base64decoded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment