Skip to main content
replaced https://tools.ietf.org/html/rfc with https://www.rfc-editor.org/rfc/rfc
Source Link

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

See also these links for similar proposals:

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

See also these links for similar proposals:

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

See also these links for similar proposals:

added 175 characters in body
Source Link
Luis Casillas
  • 11k
  • 2
  • 33
  • 42

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

See also these links for similar proposals:

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

See also these links for similar proposals:

deleted 280 characters in body
Source Link
Luis Casillas
  • 11k
  • 2
  • 33
  • 42

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

An attacker who eavesdrops on the communication learns username, user_salt and client_hashBoth protocols should be executed over an authenticated, but learns neither server_salt norconfidential channel server_hash(e. This enhances the security but is not a requisiteg. though, because an attackerSSL connection). An eavesdropper who does somehow learn server_salt andsees server_hashclient_hash still haswould be able to perform a regular password cracking attack (same as against a stolen password database)impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

An attacker who eavesdrops on the communication learns username, user_salt and client_hash, but learns neither server_salt nor server_hash. This enhances the security but is not a requisite. though, because an attacker who does somehow learn server_salt and server_hash still has to perform a regular password cracking attack (same as against a stolen password database).

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

The server certainly needs to store a verifier for every password entry. Our verifiers will be (user_salt, server_salt, server_hash) triples, where:

  • user_salt and server_salt are random 16 byte arrays.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)), where:
  • pwhash denotes a "slow" password hashing function like PBKDF2, bcrypt, scrypt or Argon2;
  • keyedhash denotes a keyed hash function like HMAC-SHA2.

Now we can use an authentication protocol like this:

  1. Client: Sends username to server;
  2. Server: Responds with the corresponding user_salt;
  3. Client: Computes client_hash = pwhash(user_salt, password);
  4. Client: Sends client_hash to server;
  5. Server: Computes server_hash = keyedhash(server_salt, client_hash);
  6. Compares server_hash to the value stored in the user's password entry.

The enrollment/password change protocol is similar:

  1. Client: authenticates with the server;
  2. Client: sends a password change request;
  3. Server: responds with a random new_client_salt;
  4. Client: computes new_client_hash = pwhash(new_client_salt, new_password);
  5. Client: sends new_client_hash;
  6. Server: selects a random new_server_salt;
  7. Server: computes new_server_hash = keyedhash(new_server_salt, new_client_hash);
  8. Server: stores (new_client_salt, new_server_salt, new_server_hash) as username's new password entry.

Both protocols should be executed over an authenticated, confidential channel (e.g., an SSL connection). An eavesdropper who sees client_hash would be able to impersonate the user.

One of the advantages of a protocol like this is that, in addition to never sending the password over the channel, it computes the slow password hashing function on the client side, which means you can crank up the function's work factor to make password cracking attacks harder.

Source Link
Luis Casillas
  • 11k
  • 2
  • 33
  • 42
Loading