Engineering @Zeta

Passwords as Second Factor: To mitigate risks of password data compromise

Password based authentication is known to have many weaknesses. The weaknesses are chiefly attributable common human behavior of reusing the same password across services, using passwords that can be easily remembered, etc. There is a lot of advice in information security books on how to safeguard password data so that even if a service is compromised the attacker will not be able to retrieve passwords of its users and then use them elsewhere. Some of the good services follow the textbook advice of using key derivation functions and enforce password complexity. However, for some time now it is known that password complexity and key derivation functions are not sufficient defenses. Large databases of passwords used by users across services are easily available to attackers. This really simplifies the password matching. It is also observed that about 13,000-15,000 patterns represent close to 100% of the passwords used by users. In one of the Fortune 100 companies, 47% of the passwords used matched top 5 patterns. So, system architects cannot assume that:

  1. Users will choose strong passwords
  2. They are immune to password compromises on other sites
  3. If their data is compromised, attackers will not be able to derive user passwords

Therefore, many services started adopting second-factor authentication. This additional factor acts as a defense when user’s password is compromised. However, the attacker will be able to confirm the password of the user before the second-factor kicks in. Also, the second factor does not eliminate or reduce the risks due to compromised data of the service.

At Zeta, we handle very sensitive information for our users. It is crucial to protect access to this information. Given the limitations of passwords discussed above, we realized that we have to go beyond the traditional practices to protect our user data.

It is common to use a one-time token (TOTP, HOTP, SMS/EMAIL OTP) as a second factor after the user is authenticated using a password. We believe OTPs are not widely used as the first factor because:

  1. of the low level of randomness, they offer
  2. people historically used passwords as the first factor and continued with it
  3. it introduces a dependency on additional devices and alternative channels of communication
  4. the potential for abuse of Email/SMS communication by attackers
  5. they are not suitable for use as the only factor of authentication

The advantage of short-lived tokens delivered to phone or Email is that the service will be able to enforce a certain minimum level of randomness. Such tokens are also not vulnerable to compromise of user’s data at other services. Given the ubiquity of SMS-capable mobile phones and accessibility of email on the web, we felt we could rely on SMS and email delivery. Therefore, we devised a mechanism using short-lived OTPs as first factor and relatively static passwords as the second factor.

In our approach, a user is partially authenticated with an OTP. After OTP authentication, we provide a cryptographically secure random salt to the user agent to perform client-side key derivation with the salt and the password provided by the user and use the derived hash as the user’s password on the server. This avoids the inherent weaknesses of the passwords used by users.

[The following content assumes prior knowledge of SHA-256, HMAC, scrypt and ECDSA]

Our Scheme

  1. When a user enters her identity (usually an email address or a phone number) to log in, the user agent generates a public and private key pair using a secure random generator on the device and communicates identity and public key to the server requesting for an authentication session.
  2. After successful initiation of the authentication session, the user is prompted for an OTP delivered to Email/SMS or a TOTP generated using software/hardware token.
  3. When the user provides the OTP, the user agent makes a request to validate this first factor provided by the user. This request for validation is digitally signed using the private key generated in step 1.
  4. On successful verification of the OTP, the first-factor validator sends a signed request to a second-factor validator. This request includes the public key shared by the user agent.
  5. The second factor authenticator passes a user specific 128-bit salt (UserSpecificSalt), to the user agent. The user agent is expected to prompt the user for the password. After accepting the password, user agent generates an HMAC SHA256 of the password using UserSpecificSalt as the key. A validation request is made to second-factor validator with the computed HMAC as the user’s password. [Given that UserSpecificSalt is cryptographically secure, the derived HMAC is also equally random, irrespective of the password used by the user]
  6. The second-factor validator considers the HMAC provided by the client as the user’s secret and performs scrypt using another user specific 256 bit key as salt (ScryptSalt). (The derived hash from the scrpyt is stored and authentication is performed against this has for all requests).
  7. Once authenticated, second-factor validator issues a digitally signed certificate for the public key presented by the user agent in the step-1, associating the public key to the user. The authentication session initiated in step-1 ends. The resultant certificate can be used to establish a data and transaction session.


  • Salts and keys are generated using the most secure source of random data available in the host environment.
  • UserSpecificSalt, ScryptSalt and the result of scrypt are encrypted using AES 256 and stored in separate data zones.
  • ECDSA with 256-bit private keys is used for all signatures and certificates. The private keys used by first-factor validator and second-factor validator for signing certificates are backed by hardware security modules.
  • Password check attempts of a user are rate limited to 5 in a window of 5 hours.
  • TLS 1.2 with Diffie-Hellman is used for data exchange between all entities involved.


The above scheme ensures that:

  1. A reusable/static password cannot be used directly on Zeta to verify if it is the user’s chosen password.
  2. Irrespective of the complexity of the password chosen by the user, the password used for authentication at the server is cryptographically secure.
  3. Zeta servers never see the password of the user.
  4. No information stored on any of the data centers is sufficient to arrive at the user’s passphrase or to impersonate the user.
  5. Compromise of all data from all servers is also insufficient to arrive at user’s chosen password.

As with almost all client-server authentication schemes, a compromised or non-compliant user agent or a compromised network will make the scheme vulnerable to a variety of threats. However, the impact of any such exploit will be limited to the user accessing the systems from such compromised environment.


Please share your comments on our approach.