== Do not limit the character set and set long max lengths for credentials ==

Some organizations restrict the 1) types of special characters and 2) length of credentials accepted by systems because of their inability to prevent SQL Injection, Cross-site scripting, command-injection and other forms of injection attacks. These restrictions, while well-intentioned, facilitate certain simple attacks such as brute force.

Some organizations restrict the 1) types of special characters and 2) length of credentials accepted by systems because of their inability to prevent SQL Injection, Cross-site scripting, command-injection and other forms of injection attacks. These restrictions, while well-intentioned, facilitate certain simple attacks such as brute force.

−

Do not apply length, character set, or encoding restrictions on the entry or storage of credentials. Continue applying encoding, escaping, masking, outright omission, and other best practices to eliminate injection risks.

+

Do not apply short or no length, character set, or encoding restrictions on the entry or storage of credentials. Continue applying encoding, escaping, masking, outright omission, and other best practices to eliminate injection risks.

−

== 2) Use a cryptographically strong credential-specific salt ==

+

A reasonable long password length is 160. Very long password policies can lead to DOS in certain circumstances[http://arstechnica.com/security/2013/09/long-passwords-are-good-but-too-much-length-can-be-bad-for-security/].

+

+

== Use a cryptographically strong credential-specific salt ==

A salt is fixed-length cryptographically-strong random value. Append credential data to the salt and use this as input to a protective function. Store the protected form appended to the salt as follows:

A salt is fixed-length cryptographically-strong random value. Append credential data to the salt and use this as input to a protective function. Store the protected form appended to the salt as follows:

Line 29:

Line 31:

Salts serve two purposes: 1) prevent the protected form from revealing two identical credentials and 2) augment entropy fed to protecting function without relying on credential complexity. The second aims to make pre-computed lookup attacks [*2] on an individual credential and time-based attacks on a population intractable.

Salts serve two purposes: 1) prevent the protected form from revealing two identical credentials and 2) augment entropy fed to protecting function without relying on credential complexity. The second aims to make pre-computed lookup attacks [*2] on an individual credential and time-based attacks on a population intractable.

−

== 3) Impose infeasible verification on attacker ==

+

== Impose infeasible verification on attacker ==

The function used to protect stored credentials should balance attacker and defender verification. The defender needs an acceptable response time for verification of users’ credentials during peak use. However, the time required to map <code><credential> → <protected form></code> must remain beyond threats’ hardware (GPU, FPGA) and technique (dictionary-based, brute force, etc) capabilities.

The function used to protect stored credentials should balance attacker and defender verification. The defender needs an acceptable response time for verification of users’ credentials during peak use. However, the time required to map <code><credential> → <protected form></code> must remain beyond threats’ hardware (GPU, FPGA) and technique (dictionary-based, brute force, etc) capabilities.

Line 48:

Line 50:

<code>return [salt] + pbkdf2([salt], [credential], c=10000); </code>

<code>return [salt] + pbkdf2([salt], [credential], c=10000); </code>

−

Designers select one-way adaptive functions to implement protect() because these functions can be configured to cost (linearly or exponentially) more than a hash function to execute. Defenders adjust work factor to keep pace with threats’ increasing hardware capabilities. Those implementing adaptive one-way functions must tune work factors so as to impede attackers while providing acceptable user experience and scale. Additionally, adaptive one-way functions do not effectively prevent reversal of common dictionary-based credentials (users with password ‘password’) regardless of user population size or salt usage.

+

Designers select one-way adaptive functions to implement protect() because these functions can be configured to cost (linearly or exponentially) more than a hash function to execute. Defenders adjust work factor to keep pace with threats’ increasing hardware capabilities. Those implementing adaptive one-way functions must tune work factors so as to impede attackers while providing acceptable user experience and scale.

+

+

Additionally, adaptive one-way functions do not effectively prevent reversal of common dictionary-based credentials (users with password ‘password’) regardless of user population size or salt usage.

==== Work Factor ====

==== Work Factor ====

−

Regardless of the chosen adaptive one-way function, developers must choose a work factor. No one single work factor fits all design situations. Experiment with and configure work factors relative to total function execution time, rather than to a particular chosen value (*WF).

+

Since resources are normally considered limited, a common rule of thumb for tuning the work factor (or cost) is to make protect() run as slow as possible without affecting the users' experience and without increasing the need for extra hardware over budget. So, if the registration and authentication's cases accept protect() taking up to 1 second, you can tune the cost so that it takes 1 second to run on your hardware. This way, it shouldn't be so slow that your users become affected, but it should also affect the attackers' attempt as much as possible.

+

+

While there is a minimum number of iterations recommended to ensure data safety, this value changes every year as technology improves. An example of the iteration count chosen by a well known company is the 10,000 iterations Apple uses for its iTunes passwords (using PBKDF2)[http://images.apple.com/ipad/business/docs/iOS_Security_May12.pdf](PDF file). However, it is critical to understand that a single work factor does not fit all designs. Experimentation is important.[*6]

The frequency and ease with which threats steal protected credentials demands “design for failure”. having detected theft, a credential storage scheme must support continued operation by marking credential data compromised and engaging alternative credential validation workflows as follows:

+

The frequency and ease with which threats steal protected credentials demands “design for failure”. Having detected theft, a credential storage scheme must support continued operation by marking credential data compromised and engaging alternative credential validation workflows as follows:

* [6] For instance, one might set work factors targeting the following run times: (1) Password-generated session key - fraction of a second; (2) User credential - ~0.5 seconds; (3) Password-generated site (or other long-lived) key - potentially a second or more.

Introduction

Media covers the theft of large collections of passwords on an almost daily basis. Media coverage of password theft discloses the password storage scheme, the weakness of that scheme, and often discloses a large population of compromised credentials that can affect multiple web sites or other applications. This article provides guidance on properly storing passwords, secret question responses, and similar credential information. Proper storage helps prevent theft, compromise, and malicious use of credentials.
Information systems store passwords and other credentials in a variety of protected forms. Common vulnerabilities allow the theft of protected passwords through attack vectors such as SQL Injection. Protected passwords can also be stolen from artifacts such as logs, dumps, and backups.

Specific guidance herein protects against stored credential theft but the bulk of guidance aims to prevent credential compromise. That is, this guidance helps designs resist revealing users’ credentials or allowing system access in the event threats steal protected credential information. For more information and a thorough treatment of this topic, refer to the Secure Password Storage Threat Model here http://goo.gl/Spvzs.

Guidance

Do not limit the character set and set long max lengths for credentials

Some organizations restrict the 1) types of special characters and 2) length of credentials accepted by systems because of their inability to prevent SQL Injection, Cross-site scripting, command-injection and other forms of injection attacks. These restrictions, while well-intentioned, facilitate certain simple attacks such as brute force.

Do not apply short or no length, character set, or encoding restrictions on the entry or storage of credentials. Continue applying encoding, escaping, masking, outright omission, and other best practices to eliminate injection risks.

A reasonable long password length is 160. Very long password policies can lead to DOS in certain circumstances[1].

Use a cryptographically strong credential-specific salt

A salt is fixed-length cryptographically-strong random value. Append credential data to the salt and use this as input to a protective function. Store the protected form appended to the salt as follows:

Generate a unique salt upon creation of each stored credential (not just per user or system wide);

Use cryptographically-strong random [*3] data;

As storage permits, use a 32bit or 64b salt (actual size dependent on protection function);

Scheme security does not depend on hiding, splitting, or otherwise obscuring the salt.

Salts serve two purposes: 1) prevent the protected form from revealing two identical credentials and 2) augment entropy fed to protecting function without relying on credential complexity. The second aims to make pre-computed lookup attacks [*2] on an individual credential and time-based attacks on a population intractable.

Impose infeasible verification on attacker

The function used to protect stored credentials should balance attacker and defender verification. The defender needs an acceptable response time for verification of users’ credentials during peak use. However, the time required to map <credential> → <protected form> must remain beyond threats’ hardware (GPU, FPGA) and technique (dictionary-based, brute force, etc) capabilities.

Two approaches facilitate this, each imperfectly.

Leverage an adaptive one-way function

Adaptive one-way functions compute a one-way (irreversible) transform. Each function allows configuration of ‘work factor’. Underlying mechanisms used to achieve irreversibility and govern work factors (such as time, space, and parallelism) vary between functions and remain unimportant to this discussion.

Select:

PBKDF2 [*4] when FIPS certification or enterprise support on many platforms is required;

Scrypt [*5] where resisting any/all hardware accelerated attacks is necessary but support isn’t.

Example protect() pseudo-code follows:

return [salt] + pbkdf2([salt], [credential], c=10000);

Designers select one-way adaptive functions to implement protect() because these functions can be configured to cost (linearly or exponentially) more than a hash function to execute. Defenders adjust work factor to keep pace with threats’ increasing hardware capabilities. Those implementing adaptive one-way functions must tune work factors so as to impede attackers while providing acceptable user experience and scale.

Additionally, adaptive one-way functions do not effectively prevent reversal of common dictionary-based credentials (users with password ‘password’) regardless of user population size or salt usage.

Work Factor

Since resources are normally considered limited, a common rule of thumb for tuning the work factor (or cost) is to make protect() run as slow as possible without affecting the users' experience and without increasing the need for extra hardware over budget. So, if the registration and authentication's cases accept protect() taking up to 1 second, you can tune the cost so that it takes 1 second to run on your hardware. This way, it shouldn't be so slow that your users become affected, but it should also affect the attackers' attempt as much as possible.

While there is a minimum number of iterations recommended to ensure data safety, this value changes every year as technology improves. An example of the iteration count chosen by a well known company is the 10,000 iterations Apple uses for its iTunes passwords (using PBKDF2)[2](PDF file). However, it is critical to understand that a single work factor does not fit all designs. Experimentation is important.[*6]

Design password storage assuming eventual compromise

The frequency and ease with which threats steal protected credentials demands “design for failure”. Having detected theft, a credential storage scheme must support continued operation by marking credential data compromised and engaging alternative credential validation workflows as follows:

[6] For instance, one might set work factors targeting the following run times: (1) Password-generated session key - fraction of a second; (2) User credential - ~0.5 seconds; (3) Password-generated site (or other long-lived) key - potentially a second or more.