Store password - to do it!
Author: Christoph Wille
Bernhard Spuida English translation: Bernhard Spuida
date:
2004/01/05
In a lot of (if you don't say almost all) Web applications (from the Web Forum to Web Store), manage user data. These user data include user login information that is also available outside the username, and is plain text. A security loophole!
Why is the storage username and password for plain text Is a security vulnerability? Then, imagine an hacker to obtain system access through an OS or server software error, and can see the user database. Now he knows any user's name and password. He can log in to a "real" user and use the user's permissions to do whatever you want, order to order in the Web store to "Character Assassination]. And you are administrators ...
How to eliminate this security threat? Decadreated a way to securely and effective ways to store password: In UNIX, the user password is stored as a so-called "salted hashes".
What is "salted hashes"
Hash is an unequal value of the value of the fixed length of any length. An example of a hash algorithm is Shai. Readers may now want to say that the password is stored as a hash value, but why?
This is because there is always a so-called "dictionary attack" to destroy the Hash Password. A good example is NT4 MD5 Hashing Password. This is a violent attack: all items in the dictionary use MD5 hash calculations to compare the results with the password database. Guess such a password is found?
The purpose of Salted hash is to add a random value (called Salt) after each password, and then calculate the hash value of the password and the SALT to prevent the above type of attack. In order to compare the password, Salt must be stored with Salted Hash. But only the attacking vector will re-encode the dictionary for each saved password and Salt, which can consume a lot of time.
As mentioned earlier, we must store three domains, the user name, Salt, and password Salted Hash, not the username and password. I also mentioned that when these data fell into the hacker, he would not be able to use a typical attack method, and it is likely that the victims of other more easily attack points.
One thing to remember: I can't send the "Password Reminder" email - can do just generate and send a new password for the user. Since there are many errors that have happened here, we start with the .NET code that generates the real random password.
Generate a password - to do it!
The entire class is created in a (C # Asp.Net) community project and another aspheute author Alexander Zeitler. This example also encounters a problem with how to generate a password and store it correctly.
For this purpose, we have created class password and have the following methods.
Namespace DotNetgermanutils
{
Public Class Password
{
Public Password (String strpassword, int nsalt)
Public Static String Createrandompassword (int PasswordLength)
Public static int createrandomsalt ()
Public String ComputeSaltedhash ()
}
}
The method of generating a new password is static, we can set the generated password length.
Public Static String Createrandompassword (int PasswordLength)
{
String _allowedchars = "Abcdefghijkmnopqrstuvwxyzabcdefghjklmnopqrstuvwxyz23456789"; Byte [] randombytes = new byte [passwordLength];
RNGCRYPTOSERVICEPROVIDER RNG = New RNGCRYPTOSERVICEPROVIDER ();
RNG.GETBYTES (Randombytes);
Char [] chars = new char [passwordLength];
Int allowedcharcount = _allowedchars.length;
For (INT i = 0; i { Chars [i] = _AllowedChars [(int) randombytes [i]% allowedcharcount]; } Return New String (Chars); } The principles here and the ASP solution in Generating A Secure Password (German) are similar, but we add some specials here: we use encrypted security random to pick passwords from "array" _allowedchars character. Class RNGCRYPTOSERVICEPROVIDER discusses in article unbreakable encryption applications. This way, we generate a real random password that can be used as the initial password - now only one SALT is required. We create a Salt Public static int createrandomsalt () { Byte [] _SALTBYTES = New byte [4]; RNGCRYPTOSERVICEPROVIDER RNG = New RNGCRYPTOSERVICEPROVIDER (); RNG.GETBYTES (_SALTBYTES); Return ((int) _SaltBytes [0]) << 24) ((int) _saltbytes [1]) << 16) ((int) _SaltBytes [2]) << 8) ((int) _saltbytes [3])); } Create a four-byte of Salt (an integer to facilitate storage in the database table). This SALT and the generated password constitute the basis for calculating Salted Hash. Calculate Salted Hash The calculation of Salted hash is an instance method that operates two member variables set by the constructor. Public Class Password { PRIVATE STRING _PASSWORD; Private int _salt; Public Password (String strpassword, int nsalt) { _password = strpassword; _salt = nsalt; } In this way, the method ComputeSaltedHash only returns Salted hash does not accept any parameters. The calculation hash value is a famous SHAI algorithm. Public String ComputeSaltedhash () { // Create Byte Array Of Password String ASCIENCODING Encoder = new asciiencoding (); Byte [] _SecretBytes = Encoder.getbytes (_Password); // Create a new salt Byte [] _SALTBYTES = New byte [4]; _SaltBytes [0] = (Byte) (_ Salt >> 24); _ SaltBytes [1] = (Byte) (_ Salt >> 16); _saltbytes [2] = (Byte) (_ Salt >> 8); _SALTBYTES [3] = (Byte) (_ SALT); // append the two arrays Byte [] tohash = new byte [_secretBytes.length]; Array.copy (_secretbytes, 0, tohash, 0, _secretBytes.length); Array.copy (_saltbytes, 0, tohash, _secretbytes.length; _saltbytes.length); SHA1 sha1 = sha1.create (); Byte [] computedhash = sha1.computehash (tohash); Return Encoder.getstring (Computehash); } Now we have all the needs of the need, then use this class. Daily class Password I created a small example to demonstrate a new password creation, a new Salt and the final Salted Hash. Using system; Using dotnetgermanutils; Namespace hashpassword { Class testApplication { [Stathread] Static void Main (String [] ARGS) { // generate a new random password string String mypassword = password.createrandompassword (8); // debug output Console.writeLine (MyPassword); // generate a new random salt INT mysalt = password.createrandomsalt (); // initialize the password class with the password and salt Password pwd = new password (mypassword, mysalt); // compute the salted hash // Note: you store the salt and the salted hash in the datbase String strshedpassword = pwd.computessaltedhash (); // debug output Console.writeLine (StrhasehedPassword); } } } The following points are very important: generate a new SALT for each user. If the two users make a clever, the same password is selected, and the Salted Hash of the two accounts will still be different. The source code shows the creation of the new password and Salt, when the user tries to log in, as follows: // Retrieve Salted Hash and Salt from User Database, Based ON Username ... Password PWD = New Password (txtpassword.text, nsaltfromDatabase); IF (PWD.ComputeSaltedHash () == strstoredsaltedhash) { // User is Authenticated SuccessFully } Else { ... Basically, this and the ordinary username / password implementation have no separate, but even if the server-side password data falls into unauthorized third-party hands, the data is more secure. in conclusion The class we demonstrate here can join your own .NET project - a gathering directly in the C # item or as other programming languages. From now on, unsafe passwords are stored without other excuses. Download code Click here to start downloading.