Jan 15, 2013

Keeping Passwords Secure

Keeping sensitive data in database has always been one of the most challenging tasks which needs deep understanding of system planning and security issues that might affect the reliability of the system. Mainly, you may implement one of the following ways to keep passwords in database:

1 – Storing Passwords as Clear-Text/Plain-Text: This option is the most insecure way of storing passwords in DB, because each password is kept as clear text without any kind of encryption/hashing algorithms used. The disadvantage of putting this into work is that anyone with access to your database will be able to read passwords and modify them. This imposes a great potential risk on your system and is not recommended in any scenario.

2 – Using Encryption Algorithms This is a more secure approach that may be taken into account. In this way, you may implement one of the Asymmetric/Symmetric algorithms to encrypt / decrypt the data. In asymmetric algorithms, the key which is used to encrypt data differs from that of decrypting; there is a public key which enables you to encrypt password and a private key allowing you to decrypt it. In contrast with Asymmetric algorithms, Symmetric algorithms use a single key for encrypting/decrypting data. Intending to implement this method, use a unique public/private key for each user. Consequently if attacker obtains the private/public key of a user, it will not be usable for other users. This algorithm is mostly common in scenarios which need password retrieval system, meaning that passwords can be recovered. So if password retrieval is not a part of your system planning, this method is not recommended.

3 – Hashing Passwords This technique is a one-way solution and makes it more secure. A “Hash Function” gets a value of variable length and produces an output with constant length. For instance, SHA256 algorithm gets the input value and generates a 256 bits output. Note that hashes of two sets of data are identical if and only if the corresponding data matches and any minor change in data causes the hash value to change dramatically, so this is a cool method when comparing large amount of data. Password recovery is also not possible when implementing this solution. When using hash functions to store scrambled data, keep in mind that if two users have the same password. the hash output will be identical and this is considered as a great vulnerability. To prevent this, you may use “Salted-Hash technique”, it means that you should add some additional data to your password and then compute the hash of new generated data. For example you may append username to the password and then hash the whole string. Consequently when authenticating users, you must first append username to entered password, hash it and then comparing it with the hash value stored in database. For more security you can generate a random salt for each user and store it in database.

.Net Framework System.Security.Cryptography namespace provides you with many cryptographic services such as Encryption/Decryption , Hashing , Random Number generation , etc.

4 – OTP – One-Time Password In spite of implementing salted hash, passwords are still stored on hard disk and are prone to be cracked. So a better approach is required here. In contrast with static passwords, one-time passwords are changed each time a user logs on to the system and usually users should carry a small hardware used for synchronizing with server.

Mainly there are two types of OTP :
  • Time-Synchronized: In this method, user should enter a password in a given period of time, otherwise it will be expired and a new password is generated. Of course this method may lead to clock-skew problem, it means that if the authentication server and the user token don’t keep the same time, authentication process will fail.
  • Counter-Synchronized: A counter is synchronized between server and user client and each time the device requests an OTP value, the counter is advanced. Like the previous solution, when user wants to logs on, he enters the password shown on the device.

For more information, visit Safer Authentication with a One-Time Password Solution.

Some Security Tips
  1. Try implementing salted hash.
  2. Enforce password policies when registering users and do not allow weak passwords.
  3. Separate authentication data ( i.e.username, password, salt, etc) and user profile data (i.e. FirstName,BirthDate, etc) into different tables.
  4. Implement strong hash algorithms like SHA256, SHA384, and SHA256 (known as SHA2).
  5. When connecting to database, use an account with the minimum required privileges.
  6. Prevent SQL Injection attacks by using stored procedures, parameterized queries and validating data before passing them to query.
  7. Obtain information on different kinds of attacks (i.e. Dictionary,Brute-Force, SQL Injection, etc) and how to defend against them.
  8. Keep security tasks and functions secure by encrypting them.
  9. Use secure connections when sending/receiving data to/from server. (I.e. SSL).

The issues that mentioned in this article are just a few tips that should be considered in order to provide a secure system and the given recommendations are all dependent upon system requirements and scenario.





Using SecureString

I’m going to elaborate on a great feature called System.Security.SecureString class which was introduced in .Net Framework 2.0. This class provides you with a secure way to store sensitive data and prevent them from being revealed by hackers. Implementing standard System.String class is not a secure way for keeping sensitive information and also swap file is in danger of being disclosed. Let’s take a look at some disadvantages of putting System.String class into work :
  1. As it’s not encrypted , anyone with access to swap file or process memory is able to read unencrypted data easily.
  2. When modifying this class , old value is not removed from the memory , so both old and new versions are kept in memory.
  3. There is not a certain way to dispose it from memory when finishing with it.
SecureString class uses DAPI to encrypt data. Information ecrypted in this way by CLR is only decrypted when accessing it and in contrast with standard System.String class , this class implements IDisposable interface so that it can be cleared out from memory and its allocated memory will be zeroed out when disposing it.
Now , let’s see an example :



using System.Security;
using System.Runtime.InteropServices;
using System;
using System.Windows.Forms;
namespace SecureStringProject
{
public class SecureStringExample
{
public void ImplementSecureString()
{
SecureString secureString = new SecureString();
///Implementing AppendChar method to add
///characters to SecureString Object.
secureString.AppendChar(‘A’);
secureString.AppendChar(‘C’);
secureString.AppendChar(‘G’);
secureString.AppendChar(‘E’);
secureString.AppendChar(‘F’);
///Implementing InsertAt method to insert a character at specified index.
secureString.InsertAt(1, ‘B’);
///Implementing SetAt method to replace character
///at specified index with new character.
secureString.SetAt(3, ‘D’);
///Implementing RemoveAt method to
///remove a character at specified index.
secureString.RemoveAt(5);
///Reading SecureStrinng content.
IntPtr pointer = Marshal.SecureStringToBSTR(secureString);
MessageBox.Show(Marshal.PtrToStringUni(pointer));
///Clearing SecureString Object.
secureString.Clear();
///Disposing SecureString Object.
secureString.Dispose();
///Free BSTR pointer allocated using
///SecureStringToBSTR method.
Marshal.ZeroFreeBSTR(pointer);
}
}
}