1. Create a new User

  1. Client get's new, random user salt from server: 's_123'
  2. Password input on the client: 'client_password'
  3. sha1(password + salt): '4f18cfffc975c298efe473377a84261a02f54858'
  4. Client send sha1 hash to the server.

2. Save user data

  1. Server split sha1 values: sha1_a: '4f18cfffc975c298' sha1_b: 'efe473377a84261a02f54858'
  2. encrypt(sha1_a, key=sha1_b): 'encrypted 4f18cfffc975c298 with efe473377a84261a02f54858'
  3. Save only the encrypted string + user salt

3. Login

  1. Client request login and get's a random challenge from server: 'c_123'
  2. User enters username and password: 'client_password'
  3. Client send username and get's user salt from server via AJAX: 's_123'
  4. on the client: sha1(password + salt): '4f18cfffc975c298efe473377a84261a02f54858'
  5. on the client: split sha1 in: sha1_a: '4f18cfffc975c298' sha1_b: 'efe473377a84261a02f54858'
  6. client generate a cnonce e.g.: cnonce = sha_hexdigest(new Date().getTime() + Math.random() + ...)
  7. client generate sha1_a with e.g.: sha1(sha_a, i, challenge, cnonce) x loop count:
    '00e736343d6dcf9b1a5ee529795353010ec68002'
  8. Client send username, sha1_a2, sha1_b and cnonce to the server.

4. validation on the server

  1. get encrypted checksum for user: 'encrypted 4f18cfffc975c298 with efe473377a84261a02f54858'
  2. decrypt(sha1checksum, key=sha1_b): '4f18cfffc975c298'
  3. server-site sha1(sha1checksum, i, challenge, cnonce) x loop count: '00e736343d6dcf9b1a5ee529795353010ec68002'
  4. compare client site generated SHA1 with the server site generated:
    00e736343d6dcf9b1a5ee529795353010ec68002 == 00e736343d6dcf9b1a5ee529795353010ec68002
<style> i { color: #000088; } strong { color: #880000 } li { line-height: 1.4em; } </style>

pseudo python script

The js_sha_login_pseudocode.py script generates the output from above: