Login Register


Secure registration and log in script - Part 1 of 2 - The registration filter_list
Author
Message
Secure registration and log in script - Part 1 of 2 - The registration #1
Secure Registration and Log in - Part 1 of 2
- The Registration -

This is the first of a two part tutorial on how to write a secure registration and log in script. I will describe every step, and include the code block for each part.

Writing a registration and log in script is not very hard. But if you want to write something that is secure both in terms of unauthorized access and securing passwords from easily being brute forced you will need to think twice about your approach. This means; securing user input through sanitation (stripping unwanted characters) and filtering and password hashing. Some might say that my approach is overkill for smaller websites, but really, there's no such thing as overkill when it comes to security. The reason for this, is because some people might use the same credentials in other locations as well, such as online bank, email, etc. So it's your job to make sure that your users stay safe when they trust you as a developer to do so.

Enough talking, let's get started.

The registration contains 4 parts:

1) Sanitize user input
2) Generate a HMAC hash using the sha512 algorithm.
3) Generate a blowfish hash of the HMAC hash.
4) Save to database

When hashing the passwords we will be using an approach that has two layers. These layers are:
1) SHA512 HMAC hash
2) Blowfish the hmac hash with a salt that has strong entropy

Step 0: Before we start
The first thing we need is to generate a key to use with HMAC.
Code:
print base64_encode(openssl_random_pseudo_bytes(256));
Copy this and store it in key.txt. This file should be stored outside the document root if possible

Step 1: Sanitize user input
It's important that you decide what characters you will allow in the username and password. You should then remove anything that does not fit these rules. Filter rules in this example is:

Username - lower and upper case letters, numbers and underscore (_)
Password - lower and upper case letters, numbers and special characters - | < > $ ? ~

Code:
// Make sure the the username applies to the filter rules before continuing if (!preg_match('/^[a-zA-Z0-9_]+$/', $_POST['username'])) { // Username contained illegal characters return; } // Make sure the the password applies to the filter rules before continuing if (!preg_match('/^[a-zA-Z0-9-|<>$?~]+$/', $_POST['password'])) { // Password contained illegal characters return; }


Step 2: SHA512 HMAC

We now grab the username and password from the $_POST array. Then we grab the key from out key.txt file and we generate a hmac using sha512 as the algorithm.

For more info on hash_hmac(), visit http://php.net/hash_hmac

Code:
$username = $_POST['username']; $password = $_POST['password']; // Get the key to use with HMAC $key = file_get_contents('/path/to/key.txt'); // Create HMAC has $password = hash_hmac('sha512', $password, $key);

Example result:
Quote:99928fa3b8447a4168ead1262e79e633d1d9d838a8b17cc4401920249cdb0d7d6cf6a46451bcf7c22b857018fd347033ac0c3889a098c126a33912b528fa3b66

Step 3: Blowfish

Next we are going to create the blowfish hash, but first we need to create a strong salt. The first 3 lines of the code below is generating a salt which is very strong and has a high cryptographical entropy. So what the code below does not is that it generates a blowfish hash of the hmac hash with a cost of 10 which will make it slow, but strong.

For more info on crypt(), visit http://php.net/crypt

Code:
// Generate a 22 character salt using strong cryptographic entropy $salt = openssl_random_pseudo_bytes(30); $salt = strtr(base64_encode($salt), '+', '.'); $salt = substr($salt, 0, 22); // Create blowfish hash $password = crypt($password, '$2y$10$' . $salt);

Example result:
Quote:$2y$10$cIoIG4G9aFVA.5xV.02wiu3eAFi1oMgbu8yOHZ0JRo3CzlGlwmkwS

Step 4: Save to database

The final thing to do now is to store the data to the database. For this we use prepared statements, and we then bind the username and password to this query before executing it.

For more info on PDO please visit http://php.net/pdo

Code:
// Connect to the database $pdo = new PDO('mysql:dbname=database;host=localhost', 'dbuser', 'dbpass'); // Prepare the statement $stmt = $pdo->prepare('INSERT INTO users (username, password) VALUES(:username, :password)'); // Bind username and password to the query $stmt->bindValue(':username', $username); $stmt->bindValue(':password', $password); // Check if query was executed successfully if (!$stmt->execute()) { // Errors occured - Handle errors } else { // Registration successfull - Continue }

Full script
Code:
// Make sure the the username applies to the filter rules before continuing if (!preg_match('/^[a-zA-Z0-9_]+$/', $_POST['username'])) { // Username contained illegal characters return; } // Make sure the the password applies to the filter rules before continuing if (!preg_match('/^[a-zA-Z0-9-|<>$?~]+$/', $_POST['password'])) { // Password contained illegal characters return; } $username = $_POST['username']; $password = $_POST['password']; // Get the key to use with HMAC $key = file_get_contents('/path/to/key.txt'); // Create HMAC has $password = hash_hmac('sha512', $password, $key); // Generate a 22 character salt using strong cryptographic entropy $salt = openssl_random_pseudo_bytes(30); $salt = strtr(base64_encode($salt), '+', '.'); $salt = substr($salt, 0, 22); // Create blowfish hash $password = crypt($password, '$2y$10$' . $salt); // Connect to the database $pdo = new PDO('mysql:dbname=sofdk;host=localhost', 'root', 'adminad'); // Prepare the statement $stmt = $pdo->prepare('INSERT INTO users (username, password) VALUES(:username, :password)'); // Bind username and password to the query $stmt->bindValue(':username', $username); $stmt->bindValue(':password', $password); // Check if query was executed successfully if (!$stmt->execute()) { // Errors occured - Handle errors } else { // Registration successfull - Continue }
"SQL Injection-a-holic"

Twitter | Security Sucks | My Blog

Reply







Users browsing this thread: