//===== Hercules Documentation ===============================
//= User Passwords
//===== By: ==================================================
//= Hercules Dev Team
//===== Current Version: =====================================
//= 20130802
//===== Description: =========================================
//= This file explain various methods of storing user
//= passwords in server's database.
//============================================================

Table of contents
 1. Introduction
 2. Plaintext
  2.1 Client-side password hashing
 3. MD5 hash
 4. bcrypt hash
  4.1 bcrypt considerations
 5. Updating your database

= Introduction =

There are 3 methods of storing user passwords in database:
 * plaintext
 * unsalted MD5 hash
 * bcrypt hash (default)

Password store method is set in login-server configuration
file 'conf/login-server.conf', setting 'pass_store_method'.
Tip: For your convenience it is recommended to always put
customized settings into 'conf/import' folder.

= Plaintext =
Passwords are stored in database unencrypted.
This option is not recommended for security reasons. In case
of database theft all passwords are immediately available to
attacker.

If you are using this option, it is recommended to switch
to default bcrypt hashing. See 'Updating your database' for
details.

== Client-side password hashing ==
There is a game client feature that enables client-side
password hashing. It is enabled by adding
 `<passwordencrypt></passwordencrypt>`
or
 `<passwordencrypt2></passwordencrypt2>`
to your 'clientinfo.xml' file.
However, this requires server to store passwords in plaintext,
therefore it's not recommended.

= MD5 hash =
Passwords are store in database as unsalted MD5 hash.
This option is not recommended for security reasons. MD5 is
considered cryptographically unsafe.

If you are using this option, it is recommended to switch
to default bcrypt hashing. See 'Updating your database' for
details.

= bcrypt =
Passwords are stored as bcrypt hashes.
This is default and recommended option. bcrypt is considered
pretty secure way of storing passwords and it is used in many
web applications.

== bcrypt considerations ==
Because bcrypt encrypts password multiple times, password
verification can take noticable amount of time. However, the
number of encryption rounds can be adjusted so that logging in
doesn't take longer than you want.

Number of rounds (also known as work factor) is set in
login-server configuration file 'conf/login-server.conf',
setting 'bcrypt_rounds'. Default value is 12.

Increasing number of rounds by 1 doubles the time required to
verify a password. Decreasing by 1 halves it.

Modern computers should be able to perform 12 rounds of bcrypt
in ~250ms (1/4th of a second). To measure performance of your
machine use login-server console command 'bcrypt benchmark'.

Note: Once the password is encrypted, the number of rounds
used to hash it is saved inside it. It is not possible to
change number of rounds for that password anymore (without
resetting it).
Thanks to that property, it is possible to change number of
rounds for new passwords while keeping old passwords
(encrypted with different number of rounds) usable. The time
required to verify them will remain the same, though.
If your players create accounts with a web control panel or
similar external tool, you need to set number of rounds there.

Tip: It is also possible to change number of rounds for some
accounts (eg. GM accounts or inter-server account),
by manually hashing them and inserting into database.

= Updating your database =
Note: Always backup your database first!

Since the only recommended way to store passwords in database
is bcrypt, this section only covers updating from plaintext
or MD5 to bcrypt.

Updating all passwords can take considerable amount of time.
The easiest way to update is by using login-server console
command 'bcrypt update'.
Char- and map-servers must be shut down during update.

During update passwords will be encrypted with number of
rounds specified in login-server configuration file, setting
'bcrypt_rounds' (default: 12).

== From plaintext ==
When performing 'bcrypt update' by login-server, all stored
passwords are hashed with bcrypt.

== From MD5 ==
This is two-step update.
1. When performing 'bcrypt update' by login-server, all stored
MD5 hashes are hashed with bcrypt. An asterisk '*' is added at
the end to distinguish them from other bcrypt hashes.
2. After first successful user login, password is hashed again
without intermediate MD5 hashing. This is done during normal
server operation and doesn't require your further attention.

== After update ==
After all passwords have been updated, you need to set
'pass_store_method' in your login-server configuration file
to '2'.
