Open Schema/Concepts/Passwords

From Jonathan Gardner's Tech Wiki
Jump to: navigation, search

Introduction

Passwords should never be stored in clear-text. In fact, they shouldn't be stored as MD5 or SHA1 sums either. Salt should always be used.

Problem

Passwords are very sensitive data. They represent a secret that no one but the user is supposed to know. Ideally, not even the computer transmitting the data from the user to the server would know the password, nor the server nor any other machine!

Clear Text

If you store passwords in clear-text, then anyone who has access to the data in the table has access to the passwords. You also have to transmit that clear-text password between the user and the server.

Simple MD5/SHA-1 Sum

If you store them as simple MD5 or SHA-1 sums, then you solve the problem of sending the password across the network in clear text.

However, they can be recovered using a rainbow table. Good passwords can't be guessed this way, but a surprising number of passwords can be guessed, particularly if the user's password has already been compromised. Besides, the server won't have the insight into what the user's password is unless you use a rainbow table yourself.

An additional problem is that accounts can be hacked with a replay attack. In this attack, the attacker simply sends the same sum that it saw the user send. There are solutions for this, but they are not simple.

Salt + Sum

If you store them as a combination of random salt plus the MD5/SHA-1 sum of the salt and the password together, then you get maximum security. A rainbow table cannot be used since the same word will have different sums with different salts.

Passwords stored and passed around like this are still subject to replay attacks with the same caveats.

Public Keys

Even the above doesn't really solve the problem of security with cryptography. The only secure method of identifying someone is the same protocol that SSH and SSL use. Namely, the server sends a challenge encrypted with the user's public key, the user decodes it with their private key and sends it back encrypted with the server's public key. If they server can decrypt it with its private key, and the response is the same, then this is proof that the server and the user are identified to each other. Note the preconditions: The server needs the user's public key and the user needs the server's public key. The mechanism for sharing public keys becomes a problem unto itself.

In reality, this is all handled with SSL. Rather than check the user's public key matches what you expected for that user (it's really a burden, anyway), you don't share any information about the password---even the salt and sum---until you have a secure connection.