security - Password hashing - Industry Standards -
i know there lot of questions already. but, haven't found definite answer question.
i know passwords stored in database prepended random salt followed hashed password. value of password never known (by server , server admins).
what standard hashing algorithm? know cryptography dynamic field , changes time. i'm asking what's current industry standard hashing.
i'm going using e-commerce site. password storage security important.
the go-to reference on topic few common languages https://crackstation.net/hashing-security.htm. i've reproduced c# version of code sample below, other languages provided
/* * password hashing pbkdf2 (http://crackstation.net/hashing-security.htm). * copyright (c) 2013, taylor hornby * rights reserved. * * redistribution , use in source , binary forms, or without * modification, permitted provided following conditions met: * * 1. redistributions of source code must retain above copyright notice, * list of conditions , following disclaimer. * * 2. redistributions in binary form must reproduce above copyright notice, * list of conditions , following disclaimer in documentation * and/or other materials provided distribution. * * software provided copyright holders , contributors "as is" * , express or implied warranties, including, not limited to, * implied warranties of merchantability , fitness particular purpose * disclaimed. in no event shall copyright holder or contributors * liable direct, indirect, incidental, special, exemplary, or * consequential damages (including, not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or business * interruption) caused , on theory of liability, whether in * contract, strict liability, or tort (including negligence or otherwise) * arising in way out of use of software, if advised of * possibility of such damage. */ using system; using system.text; using system.security.cryptography; namespace passwordhash { /// <summary> /// salted password hashing pbkdf2-sha1. /// author: havoc @ defuse.ca /// www: http://crackstation.net/hashing-security.htm /// compatibility: .net 3.0 , later. /// </summary> public class passwordhash { // following constants may changed without breaking existing hashes. public const int salt_byte_size = 24; public const int hash_byte_size = 24; public const int pbkdf2_iterations = 1000; public const int iteration_index = 0; public const int salt_index = 1; public const int pbkdf2_index = 2; /// <summary> /// creates salted pbkdf2 hash of password. /// </summary> /// <param name="password">the password hash.</param> /// <returns>the hash of password.</returns> public static string createhash(string password) { // generate random salt rngcryptoserviceprovider csprng = new rngcryptoserviceprovider(); byte[] salt = new byte[salt_byte_size]; csprng.getbytes(salt); // hash password , encode parameters byte[] hash = pbkdf2(password, salt, pbkdf2_iterations, hash_byte_size); return pbkdf2_iterations + ":" + convert.tobase64string(salt) + ":" + convert.tobase64string(hash); } /// <summary> /// validates password given hash of correct one. /// </summary> /// <param name="password">the password check.</param> /// <param name="correcthash">a hash of correct password.</param> /// <returns>true if password correct. false otherwise.</returns> public static bool validatepassword(string password, string correcthash) { // extract parameters hash char[] delimiter = { ':' }; string[] split = correcthash.split(delimiter); int iterations = int32.parse(split[iteration_index]); byte[] salt = convert.frombase64string(split[salt_index]); byte[] hash = convert.frombase64string(split[pbkdf2_index]); byte[] testhash = pbkdf2(password, salt, iterations, hash.length); return slowequals(hash, testhash); } /// <summary> /// compares 2 byte arrays in length-constant time. comparison /// method used password hashes cannot extracted /// on-line systems using timing attack , attacked off-line. /// </summary> /// <param name="a">the first byte array.</param> /// <param name="b">the second byte array.</param> /// <returns>true if both byte arrays equal. false otherwise.</returns> private static bool slowequals(byte[] a, byte[] b) { uint diff = (uint)a.length ^ (uint)b.length; (int = 0; < a.length && < b.length; i++) diff |= (uint)(a[i] ^ b[i]); return diff == 0; } /// <summary> /// computes pbkdf2-sha1 hash of password. /// </summary> /// <param name="password">the password hash.</param> /// <param name="salt">the salt.</param> /// <param name="iterations">the pbkdf2 iteration count.</param> /// <param name="outputbytes">the length of hash generate, in bytes.</param> /// <returns>a hash of password.</returns> private static byte[] pbkdf2(string password, byte[] salt, int iterations, int outputbytes) { rfc2898derivebytes pbkdf2 = new rfc2898derivebytes(password, salt); pbkdf2.iterationcount = iterations; return pbkdf2.getbytes(outputbytes); } } }
Comments
Post a Comment