Skip to content

Conversation

@sydseter
Copy link
Collaborator

This PR closes #3199

Description

Please see discussions under #3199


[x] I have read the contributing guidelines.

Guidelines for Pull Requests (you can delete this section after reading):

  • Please ensure that your content follows the style guide.
  • If you are working on Porting MASTG v1 Tests to v2, refer to this document.
  • If you are working on new MASWE, tests, or demos, refer to this document.

@sydseter
Copy link
Collaborator Author

Saw your comment about opening after merging. I’ll keep it closed for now.

@sydseter sydseter reopened this Jul 13, 2025
@sydseter
Copy link
Collaborator Author

This is currently in draft state awaiting #3199

@cpholguera
Copy link
Collaborator

Please pull the latest master and resolve any conflicts. Thanks!

@cpholguera cpholguera requested a review from TheDauntless July 17, 2025 05:44
@sydseter
Copy link
Collaborator Author

completly forgot about this one. I'll clean it up now and have a look at the comments on #3379

@cpholguera cpholguera requested a review from Copilot August 31, 2025 18:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the cryptography testing documentation to provide more comprehensive guidance on key derivation functions (KDFs) and improper random number generation. The changes expand the existing content with detailed explanations and best practices.

Key Changes:

  • Significantly expanded the "Improper Key Derivation Functions" section with detailed explanations of KDF types and use cases
  • Added comprehensive guidance on choosing appropriate KDFs for different scenarios (cryptographic vs password storage)
  • Enhanced the "Improper Random Number Generation" section with clearer explanations of CSPRNGs

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@cpholguera cpholguera requested a review from Diolor October 29, 2025 09:24
Copy link
Collaborator

@Diolor Diolor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this improvement! I suggest few changes of the read flow to the already great context! Sorry for the huge chunk 🙈

sydseter and others added 5 commits October 30, 2025 23:01
Clarified the role of Key Derivation Functions (KDFs) in cryptography, emphasizing their importance for both key generation and password storage. Added recommendations for selecting and implementing KDFs, including the use of secure hash functions and appropriate iteration counts.
Clarified recommendations for using KDFs and password hashing algorithms, including iteration counts and suitable algorithms.
@sydseter sydseter requested a review from Diolor November 3, 2025 12:38
Copy link
Collaborator

@Diolor Diolor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think content is valuable @sydseter! I focused mostly on readability.
Reading those paragraphs at first was a bit hard at first to understand, so I made a few recommendations.


Ensure that passwords aren't directly passed into an encryption function. Instead, the user-supplied password should be passed into a KDF to create a cryptographic key. Choose an appropriate iteration count when using password derivation functions. For example, [NIST recommends an iteration count of at least 10,000 for PBKDF2](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5 "NIST Special Publication 800-63B") and [for critical keys where user-perceived performance is not critical at least 10,000,000](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf "NIST Special Publication 800-132"). For critical keys, it is recommended to consider implementation of algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [Argon2](https://github.com/p-h-c/phc-winner-argon2 "Argon2").
KDFs derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF). When discussing KDFs in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password hashing and storage. Therefore, this chapter focuses primarily on KDFs in the context of cryptographic key derivation, not password storage. For general advice on password storage, please refer to the [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).
In short, we recommend:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a few new lines also in the following paragraphs for readability.

Suggested change
In short, we recommend:
In short, we recommend:

In short, we recommend:

- When using a KDF for cryptographic operations, always select **a recommended and approved KDF** and implement it according to the latest standards and the software provider's documentation.
- Only use KDFs based on **secure hash functions** - that is, hashes for which no practical pre-image or length-extension attacks are known, and where directly attacking the KDF is computationally infeasible.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Only use KDFs based on **secure hash functions** - that is, hashes for which no practical pre-image or length-extension attacks are known, and where directly attacking the KDF is computationally infeasible.
- Only use KDFs based on **secure hash functions** - weak hashes may be susceptible to attacks (i.e. preimage, length-extension)


- When using a KDF for cryptographic operations, always select **a recommended and approved KDF** and implement it according to the latest standards and the software provider's documentation.
- Only use KDFs based on **secure hash functions** - that is, hashes for which no practical pre-image or length-extension attacks are known, and where directly attacking the KDF is computationally infeasible.
- Avoid combining **user-supplied input** (such as passwords) directly with HMAC Key Derivation Function (HKDF), as this can make **pre-image attacks by password crackers** significantly easier.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Avoid combining **user-supplied input** (such as passwords) directly with HMAC Key Derivation Function (HKDF), as this can make **pre-image attacks by password crackers** significantly easier.
- Avoid combining **user-supplied input** (such as passwords) directly with HMAC Key Derivation Function (HKDF). This can make **preimage attacks by password crackers** significantly easier.

- Only use KDFs based on **secure hash functions** - that is, hashes for which no practical pre-image or length-extension attacks are known, and where directly attacking the KDF is computationally infeasible.
- Avoid combining **user-supplied input** (such as passwords) directly with HMAC Key Derivation Function (HKDF), as this can make **pre-image attacks by password crackers** significantly easier.

Choose a KDF that uses an adaptive hash function that can be configured to change the amount of computational effort needed to compute the hash, such as the number of iterations ("stretching") or the amount of memory required. Some hash functions perform salting automatically. These functions can significantly increase the overhead of brute-force attacks, including rainbow-table attacks. Finally, with computing power becoming faster and cheaper, the technique can be reconfigured to increase the workload without requiring a complete replacement of the algorithm in use.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor rewrite for readability:

Suggested change
Choose a KDF that uses an adaptive hash function that can be configured to change the amount of computational effort needed to compute the hash, such as the number of iterations ("stretching") or the amount of memory required. Some hash functions perform salting automatically. These functions can significantly increase the overhead of brute-force attacks, including rainbow-table attacks. Finally, with computing power becoming faster and cheaper, the technique can be reconfigured to increase the workload without requiring a complete replacement of the algorithm in use.
Choose a KDF that uses a tunable, adaptive hash function - one that lets you adjust how much computational work is required, such as by increasing the number of iterations ("stretching") or the amount of memory it consumes. Modern KDFs often handle salting automatically. These properties make brute-force and rainbow-table attacks far more expensive for an attacker. As hardware becomes faster and cheaper over time, the cost parameters can simply be raised, without needing to replace the underlying algorithm.

- Avoid combining **user-supplied input** (such as passwords) directly with HMAC Key Derivation Function (HKDF), as this can make **pre-image attacks by password crackers** significantly easier.

Choose a KDF that uses an adaptive hash function that can be configured to change the amount of computational effort needed to compute the hash, such as the number of iterations ("stretching") or the amount of memory required. Some hash functions perform salting automatically. These functions can significantly increase the overhead of brute-force attacks, including rainbow-table attacks. Finally, with computing power becoming faster and cheaper, the technique can be reconfigured to increase the workload without requiring a complete replacement of the algorithm in use.
Some hash functions that have one or more of these desired properties include [scrypt](https://www.tarsnap.com/scrypt.html) and [PBKDF2](https://www.rfc-editor.org/rfc/rfc2898). While there is active debate over which is most effective, both are stronger than using salts with hash functions and incur very little computational overhead. Note that using these functions can affect performance, so they require special consideration. However, their configurability provides finer control over CPU and memory usage, allowing them to be adjusted to suit the environment's needs. When CPU and memory performance are a challenge, consider increasing the desired bit length of the derived key rather than increasing the iteration count (e.g., using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible to brute-force attacks, but it should be acceptable as long as you stay within the recommended guidelines.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this into two paragraphs reads a bit better. I also dropped the "debate" to make it more "timeless".

Suggested change
Some hash functions that have one or more of these desired properties include [scrypt](https://www.tarsnap.com/scrypt.html) and [PBKDF2](https://www.rfc-editor.org/rfc/rfc2898). While there is active debate over which is most effective, both are stronger than using salts with hash functions and incur very little computational overhead. Note that using these functions can affect performance, so they require special consideration. However, their configurability provides finer control over CPU and memory usage, allowing them to be adjusted to suit the environment's needs. When CPU and memory performance are a challenge, consider increasing the desired bit length of the derived key rather than increasing the iteration count (e.g., using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible to brute-force attacks, but it should be acceptable as long as you stay within the recommended guidelines.
Some hash functions and KDFs that offer these adaptive properties include [scrypt](https://www.tarsnap.com/scrypt.html) and [PBKDF2](https://www.rfc-editor.org/rfc/rfc2898). Both are significantly more secure than using plain hash functions with salts, and they introduce only limited computational overhead. Their tunable parameters let you precisely control CPU and memory usage, tailoring the workload to the environment.
Be aware that these functions can impact performance, so they should be configured carefully. In environments where CPU or memory is constrained, you can sometimes increase the derived key’s bit length (for example, using HMAC-SHA512 instead of HMAC-SHA256) rather than drastically increasing the iteration count. This may slightly increase susceptibility to brute-force attacks, but it remains acceptable as long as the configuration follows recommended security guidelines.


Choose a KDF that uses an adaptive hash function that can be configured to change the amount of computational effort needed to compute the hash, such as the number of iterations ("stretching") or the amount of memory required. Some hash functions perform salting automatically. These functions can significantly increase the overhead of brute-force attacks, including rainbow-table attacks. Finally, with computing power becoming faster and cheaper, the technique can be reconfigured to increase the workload without requiring a complete replacement of the algorithm in use.
Some hash functions that have one or more of these desired properties include [scrypt](https://www.tarsnap.com/scrypt.html) and [PBKDF2](https://www.rfc-editor.org/rfc/rfc2898). While there is active debate over which is most effective, both are stronger than using salts with hash functions and incur very little computational overhead. Note that using these functions can affect performance, so they require special consideration. However, their configurability provides finer control over CPU and memory usage, allowing them to be adjusted to suit the environment's needs. When CPU and memory performance are a challenge, consider increasing the desired bit length of the derived key rather than increasing the iteration count (e.g., using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible to brute-force attacks, but it should be acceptable as long as you stay within the recommended guidelines.
Unfortunately, "brute-force" attacks are quite likely to succeed when users select passwords and pins with little or no entropy, which is required for cryptographic keys. Therefore, ensure that passwords and pins aren't passed directly to an HKDF. The input key to a key-derivation function is called a key-derivation key (KDK). A KDK **shall** be a cryptographic key, but the KDK used as an input to a recommended KDF can, for example, be generated by an approved cryptographic random bit generator, e.g. by a deterministic random bit generator (see: [NIST 800-108, rev 1](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")) ([NIST, 2022](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")). When the input is user-controlled, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 should be used as a KDF to provide sufficient computational effort. Do not use an HKDF or any other integrity-based hashing algorithm like MD5, SHA-1, SHA-2, or SHA-3 for this purpose. HKDFs, like SHA-3, aren't designed for low-entropy inputs. In the context of key derivation, these should only be used for key stretching or key diversification of randomly generated keys.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Splitting into 3 paragraphs for readability

Suggested change
Unfortunately, "brute-force" attacks are quite likely to succeed when users select passwords and pins with little or no entropy, which is required for cryptographic keys. Therefore, ensure that passwords and pins aren't passed directly to an HKDF. The input key to a key-derivation function is called a key-derivation key (KDK). A KDK **shall** be a cryptographic key, but the KDK used as an input to a recommended KDF can, for example, be generated by an approved cryptographic random bit generator, e.g. by a deterministic random bit generator (see: [NIST 800-108, rev 1](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")) ([NIST, 2022](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")). When the input is user-controlled, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 should be used as a KDF to provide sufficient computational effort. Do not use an HKDF or any other integrity-based hashing algorithm like MD5, SHA-1, SHA-2, or SHA-3 for this purpose. HKDFs, like SHA-3, aren't designed for low-entropy inputs. In the context of key derivation, these should only be used for key stretching or key diversification of randomly generated keys.
Users often choose passwords or PINs with very low entropy, making them vulnerable to brute-force attacks. For this reason, passwords and PINs must not be fed directly into an HKDF. The input key to a key-derivation function is known as a key-derivation key (KDK). A KDK **shall** be a proper cryptographic key. For example, it can be generated using an approved cryptographic random bit generator, such as a deterministic random bit generator (see [NIST 800-108, rev 1](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final)).
When the input is provided by a user, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 must be used to ensure adequate computational cost. These functions are specifically designed to handle low-entropy inputs.
Do not use an HKDF or any other integrity-oriented hash function (such as MD5, SHA-1, SHA-2, or SHA-3) for password-based key derivation. HKDF and SHA-3 are not designed to harden low-entropy secrets. In the context of key derivation, they should only be used for key stretching or diversification when the original key material is already randomly generated and has high entropy.

Choose a KDF that uses an adaptive hash function that can be configured to change the amount of computational effort needed to compute the hash, such as the number of iterations ("stretching") or the amount of memory required. Some hash functions perform salting automatically. These functions can significantly increase the overhead of brute-force attacks, including rainbow-table attacks. Finally, with computing power becoming faster and cheaper, the technique can be reconfigured to increase the workload without requiring a complete replacement of the algorithm in use.
Some hash functions that have one or more of these desired properties include [scrypt](https://www.tarsnap.com/scrypt.html) and [PBKDF2](https://www.rfc-editor.org/rfc/rfc2898). While there is active debate over which is most effective, both are stronger than using salts with hash functions and incur very little computational overhead. Note that using these functions can affect performance, so they require special consideration. However, their configurability provides finer control over CPU and memory usage, allowing them to be adjusted to suit the environment's needs. When CPU and memory performance are a challenge, consider increasing the desired bit length of the derived key rather than increasing the iteration count (e.g., using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible to brute-force attacks, but it should be acceptable as long as you stay within the recommended guidelines.
Unfortunately, "brute-force" attacks are quite likely to succeed when users select passwords and pins with little or no entropy, which is required for cryptographic keys. Therefore, ensure that passwords and pins aren't passed directly to an HKDF. The input key to a key-derivation function is called a key-derivation key (KDK). A KDK **shall** be a cryptographic key, but the KDK used as an input to a recommended KDF can, for example, be generated by an approved cryptographic random bit generator, e.g. by a deterministic random bit generator (see: [NIST 800-108, rev 1](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")) ([NIST, 2022](https://csrc.nist.gov/pubs/sp/800/108/r1/upd1/final "NIST: Recommendation for Key Derivation Using Pseudorandom Functions")). When the input is user-controlled, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 should be used as a KDF to provide sufficient computational effort. Do not use an HKDF or any other integrity-based hashing algorithm like MD5, SHA-1, SHA-2, or SHA-3 for this purpose. HKDFs, like SHA-3, aren't designed for low-entropy inputs. In the context of key derivation, these should only be used for key stretching or key diversification of randomly generated keys.
When using a password hashing algorithm as a KDF, also ensure you choose an appropriate iteration count that provides sufficient computational effort, making password- or secret-cracking attacks infeasible or expensive. For example, [NIST recommends an iteration count of at least 10,000 for PBKDF2](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5 "NIST Special Publication 800-63B") and [for critical keys where user-perceived performance is not critical at least 10,000,000](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf "NIST Special Publication 800-132"). For critical keys, it is recommended to implement algorithms recognized by the [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC"), such as [Argon2](https://github.com/p-h-c/phc-winner-argon2 "Argon2"). Also see ["OWASP Password Storage Cheat Sheet"](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#introduction "OWASP Cheat Sheet Series: Password Storage Cheat Sheet") for recommendations on iteration count when using KDFs using Argon2, scrypt, bcrypt, or PBKDF2.
Copy link
Collaborator

@Diolor Diolor Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using a password hashing algorithm as a KDF, also ensure you choose an appropriate iteration count that provides sufficient computational effort, making password- or secret-cracking attacks infeasible or expensive. For example, [NIST recommends an iteration count of at least 10,000 for PBKDF2](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5 "NIST Special Publication 800-63B") and [for critical keys where user-perceived performance is not critical at least 10,000,000](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf "NIST Special Publication 800-132"). For critical keys, it is recommended to implement algorithms recognized by the [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC"), such as [Argon2](https://github.com/p-h-c/phc-winner-argon2 "Argon2"). Also see ["OWASP Password Storage Cheat Sheet"](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#introduction "OWASP Cheat Sheet Series: Password Storage Cheat Sheet") for recommendations on iteration count when using KDFs using Argon2, scrypt, bcrypt, or PBKDF2.

Isn't that a bit contrary to the initial Therefore, this chapter focuses primarily on KDFs in the context of cryptographic key derivation, not password storage. ?

- Password storage: To prevent attackers from reading stolen passwords after a data breach, passwords should be stored as hashes generated by a resource-intensive Key Derivation Function (KDF).

Ensure that passwords aren't directly passed into an encryption function. Instead, the user-supplied password should be passed into a KDF to create a cryptographic key. Choose an appropriate iteration count when using password derivation functions. For example, [NIST recommends an iteration count of at least 10,000 for PBKDF2](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5 "NIST Special Publication 800-63B") and [for critical keys where user-perceived performance is not critical at least 10,000,000](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf "NIST Special Publication 800-132"). For critical keys, it is recommended to consider implementation of algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [Argon2](https://github.com/p-h-c/phc-winner-argon2 "Argon2").
KDFs derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF). When discussing KDFs in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password hashing and storage. Therefore, this chapter focuses primarily on KDFs in the context of cryptographic key derivation, not password storage. For general advice on password storage, please refer to the [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
KDFs derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF). When discussing KDFs in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password hashing and storage. Therefore, this chapter focuses primarily on KDFs in the context of cryptographic key derivation, not password storage. For general advice on password storage, please refer to the [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).
KDFs use a pseudorandom function (PRF) to derive cryptographically suitable key material from passwords or other input sources. In the context of mobile applications, KDFs are almost always used for cryptographic key derivation, not password hashing or password storage. Therefore, this chapter focuses exclusively on KDFs for cryptographic key derivation. For general advice on password storage, please refer to the [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).

Easier to read?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants