Changes between Initial Version and Version 1 of PasswordHash


Ignore:
Timestamp:
Feb 16, 2018, 2:55:42 PM (7 years ago)
Author:
Kevin Reed
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PasswordHash

    v1 v1  
     1= Overview =
     2Currently BOINC stores passwords in the database using following hash:
     3
     4{{{
     5md5_string(passwd+email_addr)
     6}}}
     7This is no longer considered to be secure for storage of passwords.   Brute force attacks on md5 hashed passwords are possible due to the speed that md5 hashes can be computed.  As a result, in the event that  the database of a BOINC project were compromised, the passwords would be at risk of being cracked.
     8
     9Due to the fact that the md5 hash of the password is computed on the client (when a user is attaching to a project), any change made to the hash algorithm will take several years before the md5 hash can be fully sunset.  As a result, it is important to get started on this change.
     10
     11This change will need to adhere to the follow goals:
     12
     13 1. A old client         should be able to register a user and/or attach a user to a old         project
     14
     15 1. A old client         should be able to register a user and/or attach a user to a updated         project
     16
     17 1. A updated         client should be able to register a user and/or attach a user to a         old project
     18
     19 1. A updated         client should be able to register a user and/or attach a user to a         updated project
     20
     21 1. A updated         project should have all passwords stored using the new hash         algorithm
     22
     23= New Hashing Function =
     24For PHP code, will will use password_hash (https://php.net/manual/en/function.password-hash.php).  We will also use a compatibility library for this to support older versions of PHP (https://github.com/ircmaxell/password_compat).  As an example of how to use password_hash:
     25
     26{{{
     27<?php
     28    require('lib/password.php');  //password_hash compatability library
     29    $passwd = "test";
     30    $passwd_hash = password_hash ( $passwd , PASSWORD_DEFAULT );
     31    echo $passwd_hash . PHP_EOL;
     32    if ( password_verify($passwd, $passwd_hash) ) {
     33        echo "Password valid" . PHP_EOL;
     34    } else {
     35        echo "Invalid password" . PHP_EOL;
     36    }
     37?>
     38}}}
     39At the moment, the new hashing will not need to be done in C code.  However, if this changes, the implementation found here: http://www.openwall.com/crypt/ can be used.
     40
     41= Approach =
     42The purpose of this change is to make the storage of the password secure.  Due to the usage of the existing md5 password hash in the client, web_rpc's and website, it would be difficult to eliminate usage of the md5 version of the hash at this time.  As a result, this change focuses simply on storing the password in a secure way.
     43
     44The password will be stored in the existing field in the database as follows:
     45
     46{{{
     47$database_password_hash = password_hash ( md5_string(passwd+email_addr) , PASSWORD_DEFAULT );
     48}}}
     49= Migration =
     50Because password_hash is designed to be computational expensive, performing an update on all passwords on the system immediately could potentially be a long running action – especially on some of the larger BOINC projects.  As a result, the system will store the password in the new format when created or updated and will “rehash” the password whenever the password is verified.
     51
     52== Verify Password ==
     53Verifying the password will look like the following:
     54
     55{{{
     56$password_hash = md5_string(passwd+email_addr);  //or passed in via web rpc
     57$database_password_hash = fetch from database for user
     58if ( $password_hash ==$database_password_hash|| password_verify($password_hash,$database_password_hash) ) {
     59    //this is a valid password
     60} else {
     61    //this is not a valid password
     62}
     63}}}
     64== Rehash Password ==
     65Every time that a password is verified, it will then be checked to see if it needs to be rehashed.  This will look like the following:
     66
     67{{{
     68$password_hash = md5_string(passwd+email_addr);  //or passed in via web rpc
     69$database_password_hash = fetch from database
     70if ( $password_hash ==$database_password_hash|| password_needs_rehash($password_hash,$database_password_hash) ) {
     71    $new_database_password_hash= password_hash ( $password_hash , PASSWORD_DEFAULT );
     72    //save $new_database_password_hash to database
     73}
     74}}}
     75This will convert the password hashes over time to the stronger hashed formula.  A script will be developed that can be used at a later time (or gradually over time) to update those password hashes that have not yet been converted.  Password hashes in the new format will start with $2$10 and are therefore easily identifiable from the md5 hashed passwords.
     76
     77= Changes =
     78The client will not require any changes nor will external systems that use the Web RPCs. 
     79
     80The website will need to be changed in order to add the new logic to validate and rehash a password and to use the new hash algorithm when stored in the database.