-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
#3379 Update 0x04g-Testing-Cryptography.md #3385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Saw your comment about opening after merging. I’ll keep it closed for now. |
|
This is currently in draft state awaiting #3199 |
|
Please pull the latest master and resolve any conflicts. Thanks! |
|
completly forgot about this one. I'll clean it up now and have a look at the comments on #3379 |
There was a problem hiding this 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.
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Diolor
left a comment
There was a problem hiding this 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 🙈
Co-authored-by: Dionysis Lorentzos <[email protected]>
Co-authored-by: Dionysis Lorentzos <[email protected]>
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.
Diolor
left a comment
There was a problem hiding this 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: |
There was a problem hiding this comment.
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.
| 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor rewrite for readability:
| 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. |
There was a problem hiding this comment.
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".
| 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. |
There was a problem hiding this comment.
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
| 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. |
There was a problem hiding this comment.
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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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?
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):