From 20f82ccd3f1ba6dd8324b42dc5895fec3afc1340 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Sun, 13 Jul 2025 20:26:37 +0200
Subject: [PATCH 01/15] Update 0x04g-Testing-Cryptography.md
---
Document/0x04g-Testing-Cryptography.md | 103 +++++++++++++++++++------
1 file changed, 79 insertions(+), 24 deletions(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index d90f791bb2e..f51c84b49c8 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -11,13 +11,13 @@ Cryptography plays an especially important role in securing the user's data - ev
The goal of cryptography is to provide constant confidentiality, data integrity, and authenticity, even in the face of an attack. Confidentiality involves ensuring data privacy through the use of encryption. Data integrity deals with data consistency and detection of tampering and modification of data through the use of hashing. Authenticity ensures that the data comes from a trusted source.
-Encryption algorithms converts plaintext data into cipher text that conceals the original content. Plaintext data can be restored from the cipher text through decryption. Encryption can be **symmetric** (encryption/decryption with same secret-key) or **asymmetric** (encryption/decryption using a public and private key pair). In general, encryption operations do not protect integrity, but some symmetric encryption modes also feature that protection.
+An encryption algorithm converts plaintext data into ciphertext, which conceals the original content. The plaintext data can be restored from the ciphertext through decryption. There are two types of encryption: **symmetric** (encryption and decryption use the same secret key) and **asymmetric** (encryption and decryption use a public and private key pair). Symmetric encryption operations do not protect data integrity unless they are used with an approved cipher mode that supports authenticated encryption with a random initialization vector (IV) that fulfills the "uniqueness" requirement [NIST SP 800-38D - "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC", 2007](https://csrc.nist.gov/pubs/sp/800/38/d/final).
**Symmetric-key encryption algorithms** use the same key for both encryption and decryption. This type of encryption is fast and suitable for bulk data processing. Since everybody who has access to the key is able to decrypt the encrypted content, this method requires careful key management and centralized control over key distribution.
**Public-key encryption algorithms** operate with two separate keys: the public key and the private key. The public key can be distributed freely while the private key shouldn't be shared with anyone. A message encrypted with the public key can only be decrypted with the private key and vice-versa. Since asymmetric encryption is several times slower than symmetric operations, it's typically only used to encrypt small amounts of data, such as symmetric keys for bulk encryption.
-**Hashing** isn't a form of encryption, but it does use cryptography. Hash functions deterministically map arbitrary pieces of data into fixed-length values. It's easy to compute the hash from the input, but very difficult (i.e. infeasible) to determine the original input from the hash. Additionally, the hash will completely change when even a single bit of the input changes. Hash functions are used for integrity verification, but don't provide an authenticity guarantee.
+**Hashing** isn't a form of encryption, but it does use cryptography. Hash functions map arbitrary pieces of data into fixed-length values in a deterministic way. While it's easy to compute the hash from the input, it's very difficult (i.e., infeasible) to determine the original input from the hash. Additionally, the hash changes completely when even a single bit of the input changes. Hash functions are used for storing passwords, verifying integrity (e.g., digital signatures or document management), and managing files. Although hash functions don't provide an authenticity guarantee, they can be combined as cryptographic primitives to do so.
**Message Authentication Codes** (MACs) combine other cryptographic mechanisms (such as symmetric encryption or hashes) with secret keys to provide both integrity and authenticity protection. However, in order to verify a MAC, multiple entities have to share the same secret key and any of those entities can generate a valid MAC. HMACs, the most commonly used type of MAC, rely on hashing as the underlying cryptographic primitive. The full name of an HMAC algorithm usually includes the underlying hash function's type (for example, HMAC-SHA256 uses the SHA-256 hash function).
@@ -46,24 +46,46 @@ The names of cryptographic APIs depend on the particular mobile platform.
Please make sure that:
- Cryptographic algorithms are up to date and in-line with industry standards. This includes, but is not limited to outdated block ciphers (e.g. DES), stream ciphers (e.g. RC4), as well as hash functions (e.g. MD5) and broken random number generators like Dual_EC_DRBG (even if they are NIST certified). All of these should be marked as insecure and should not be used and removed from the application and server.
-- Key lengths are in-line with industry standards and provide protection for sufficient amount of time. A comparison of different key lengths and protection they provide taking into account Moore's law is available [online](https://www.keylength.com/ "Keylength comparison").
+- Key lengths are in line with industry standards and provide sufficient protection over a long period of time. A comparison of different key lengths and the protection they provide, taking Moore's Law into account, is available [online](https://www.keylength.com/ "Keylength comparison").
+- Through [NIST SP 800-131A - "Transitioning the Use of Cryptographic Algorithms and Key Lengths", 2024](https://csrc.nist.gov/pubs/sp/800/131/a/r3/ipd), NIST provides recommendations and guidance on aligning with future recommendations and transitioning to stronger cryptographic keys and more robust algorithms.
- Cryptographic means are not mixed with each other: e.g. you do not sign with a public key, or try to reuse a key pair used for a signature to do encryption.
- Cryptographic parameters are well defined within reasonable range. This includes, but is not limited to: cryptographic salt, which should be at least the same length as hash function output, reasonable choice of password derivation function and iteration count (e.g. PBKDF2, scrypt or bcrypt), IVs being random and unique, fit-for-purpose block encryption modes (e.g. ECB should not be used, except specific cases), key management being done properly (e.g. 3DES should have three independent keys) and so on.
-The following algorithms are recommended:
+Recommended algorithms:
- Confidentiality algorithms: AES-GCM-256 or ChaCha20-Poly1305
- Integrity algorithms: SHA-256, SHA-384, SHA-512, BLAKE3, the SHA-3 family
-- Digital signature algorithms: RSA (3072 bits and higher), ECDSA with NIST P-384
+- Digital signature algorithms: RSA (3072 bits and higher), ECDSA with NIST P-384 or EdDSA with Edwards448.
- Key establishment algorithms: RSA (3072 bits and higher), DH (3072 bits or higher), ECDH with NIST P-384
+**Please note:** The recommendations are based on the current industry perception of what is considered appropriate. They align with NIST recommendations beyond 2030 but do not necessarily take into account advancements in quantum computing. For advice on post-quantum cryptography, please see the ["Post-Quantum"](#post-quantum) section below.
+
Additionally, you should always rely on secure hardware (if available) for storing encryption keys, performing cryptographic operations, etc.
For more information on algorithm choice and best practices, see the following resources:
-- ["Commercial National Security Algorithm Suite and Quantum Computing FAQ"](https://cryptome.org/2016/01/CNSA-Suite-and-Quantum-Computing-FAQ.pdf "Commercial National Security Algorithm Suite and Quantum Computing FAQ")
+- ["Commercial National Security Algorithm Suite and Quantum Computing FAQ"](https://web.archive.org/web/20250305234320/https://cryptome.org/2016/01/CNSA-Suite-and-Quantum-Computing-FAQ.pdf "Commercial National Security Algorithm Suite and Quantum Computing FAQ")
- [NIST recommendations (2019)](https://www.keylength.com/en/4/ "NIST recommendations")
- [BSI recommendations (2019)](https://www.keylength.com/en/8/ "BSI recommendations")
+- [NIST SP 800-56B Revision 2 - "Recommendation for Pair-Wise Key-Establishment Using Integer Factorization Cryptography", 2019](https://csrc.nist.gov/pubs/sp/800/56/b/r2/final): NIST advises using RSA-based key-transport schemes with a minimum modulus length of at least 2048 bits.
+- [NIST SP 800-56A Revision 3 - "Recommendation for Pair-Wise Key-Establishment Schemes Using Discrete Logarithm Cryptography", 2018](https://csrc.nist.gov/pubs/sp/800/56/a/r3/final): NIST advises using ECC-based key-agreement schemes, such as Elliptic Curve Diffie-Hellman (ECDH), utilizing curves from P-224 to P-521.
+- [FIPS 186-5 - "Digital Signature Standard (DSS)", 2023](https://csrc.nist.gov/pubs/fips/186-5/final): NIST approves RSA, ECDSA, and EdDSA for digital signature generation. DSA should only be used to verify previously generated signatures.
+- [NIST SP 800-186 - "Recommendations for Discrete Logarithm-Based Cryptography: Elliptic Curve Domain Parameters", 2023](https://csrc.nist.gov/pubs/sp/800/186/final): Provides recommendations for elliptic curve domain parameters used in discrete logarithm-based cryptography.
+
+## Post-Quantum
+
+### Public-key encryption algorithms
+
+In 2024, NIST approved CRYSTALS-Kyber as a post-quantum key encapsulation mechanism (KEM) for establishing a shared secret over a public channel. This shared secret can then be used with symmetric-key algorithms for encryption and decryption.
+
+- [FIPS 203 - "Module-Lattice-Based Key-Encapsulation Mechanism Standard", 2024](https://csrc.nist.gov/pubs/fips/203/final): Specifies CRYSTALS-Kyber as the standard for post-quantum key encapsulation.
+
+## Signatures
+
+In 2024, NIST approved SLH-DSA and ML-DSA as recommended digital signature algorithms for post-quantum signature generation and verification.
+
+- [FIPS 205 - "Stateless Hash-Based Digital Signature Standard", 2024](https://csrc.nist.gov/pubs/fips/205/final): Specifies SLH-DSA for post-quantum digital signatures.
+- [FIPS 204 - "Module-Lattice-Based Digital Signature Standard", 2024](https://csrc.nist.gov/pubs/fips/204/final): Specifies ML-DSA for post-quantum digital signatures.
## Common Configuration Issues
@@ -94,49 +116,78 @@ If the app relies on an additional encrypted container stored in app data, check
Secret keys must be stored in secure device storage whenever symmetric cryptography is used in mobile apps. For more information on the platform-specific APIs, see the "[Data Storage on Android](0x05d-Testing-Data-Storage.md)" and "[Data Storage on iOS](0x06d-Testing-Data-Storage.md)" chapters.
-### Weak Key Generation Functions
+### Improper Key Derivation Functions
+
+When discussing key derivation functions (KDFs) in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password storage. This chapter focuses primarily on KDF in the context of cryptographic key derivation, rather than 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 derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF).
+
+Different KDFs are suitable for different tasks such as:
-Cryptographic algorithms (such as symmetric encryption or some MACs) expect a secret input of a given size. For example, AES uses a key of exactly 16 bytes. A native implementation might use the user-supplied password directly as an input key. Using a user-supplied password as an input key has the following problems:
+- Cryptographic key derivation:
+ - Together with a non-secret parameter to derive one or more keys from a common secret value. Also known as known as "key diversification"
+ - As components of multiparty key-agreement protocols (e.g: [KDF1](https://en.wikipedia.org/wiki/IEEE_P1363)).
+ - To derive keys from secret passwords or passphrases.
+ - To derive keys of different length from the ones provided (e.g: [PBKDF2HMAC](https://en.wikipedia.org/wiki/PBKDF2) or [HKDF](https://en.wikipedia.org/wiki/HKDF)).
+ - [Key stretching](https://en.wikipedia.org/wiki/Key_stretching) and [key strengthening](https://en.wikipedia.org/wiki/Key_derivation_function#Key_stretching_and_key_strengthening).
-- If the password is smaller than the key, the full key space isn't used. The remaining space is padded (spaces are sometimes used for padding).
-- A user-supplied password will realistically consist mostly of displayable and pronounceable characters. Therefore, only some of the possible 256 ASCII characters are used and entropy is decreased by approximately a factor of four.
+- Password storage:
+ - In order to ensure attacker's can't use a stolen password even in the event of a data breach, passwords are stored as hashes computed through a computationally intensive KDF. The ideal password storage's KDF should be demanding on both computational and memory resources.
-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").
+Source: ([Wikipedia, 2025.02.21"](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function"))
-### Weak Random Number Generators
+When using a KDF for cryptographic operations always ensure to use a recommended and approved KDF properly according to the latest recommendations and the software provider's documentation. E.g Only using a key derivation functions that is constructed from hashes against which no non-trivial pre-image or length-extension attacks are known and where attacking the key derivation function directly is infeasible. Using user-supplied input together with HKDF will make it easy for password crackers to execute a preimage attack.
-It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (RNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. Cryptographically secure RNGs generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced).
+Choose a KDF that use 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 for a brute force attack compared to intentionally-fast functions. For example, rainbow table attacks can become infeasible due to the high computing overhead. Finally, since computing power gets faster and cheaper over time, the technique can be reconfigured to increase the workload without forcing an entire replacement of the algorithm in use.
-Mobile SDKs offer standard implementations of RNG algorithms that produce numbers with sufficient artificial randomness. We'll introduce the available APIs in the Android and iOS specific sections.
+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 about which of these is the most effective, they are all stronger than using salts with hash functions with very little computing overhead.
+
+Note that using these functions can have an impact on performance, so they require special consideration to avoid denial-of-service attacks. However, their configurability provides finer control over how much CPU and memory is used, so it could be adjusted to suit the environment's needs. In the case where CPU and memory performance is a challenge try adjusting desired bit-length of the derived key instead of increasing the iteration account (e.g using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible by brute-force attacks, but should be acceptable as long as you keep yourself within recommended guidelines.
+
+Unfortunately, "brute-force" attacks are quite liable to succeed where users selects passwords and pins with none or with too little entropy than what is required for cryptographic keys. Therefore, ensure that passwords and pins aren't directly passed into a HKDF. The key that is input 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 key-derivation functions 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")).
+In cases where the input is user-controlled, use password hashing algorithm like Argon2, scrypt, bcrypt or PBKDF2 as a key derivation function to provide a sufficient level of computational effort.
+When using a password hashing algorithm as a KDF, also ensure to choose an appropriate iteration count that can provide sufficient computational efforts. Meaning that they make 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 implementation algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [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 recommendation on iteration count when using key derivation functions using Argon2, scrypt, bcrypt or PBKDF2.
+
+### Improper Random Number Generation
+
+It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (PRNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. Cryptographically secure PRNGs (CSPRNG) generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced).
+
+PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
+
+Mobile SDKs offer standard implementations of PRNG algorithms that produce numbers with sufficient artificial randomness. We'll introduce the available APIs in the Android and iOS-specific sections.
+
+### Improper Hashing
+
+Make sure to choose a hash function that is built for the purpose you intend it for.
+When hashes are needed for integrity checks, choose an algorithm that is sufficiently collision resistant, such as the integrity algorithms SHA-256, SHA-384, SHA-512, BLAKE3, and the SHA-3 family. Choosing a risky or broken algorithm may compromise the integrity and authenticity of data at rest and in transit. Also keep in mind that hash functions used for integrity checks, like the SHA series, should not be used for key derivation together with predictable input or in password hashing.
### Custom Implementations of Cryptography
-Inventing proprietary cryptographic functions is time consuming, difficult, and likely to fail. Instead, we can use well-known algorithms that are widely regarded as secure. Mobile operating systems offer standard cryptographic APIs that implement those algorithms.
+Inventing proprietary cryptographic functions is time-consuming, difficult, and likely to fail. Instead, we can use well-known algorithms that are widely regarded as secure. Mobile operating systems offer standard cryptographic APIs that implement those algorithms.
Carefully inspect all the cryptographic methods used within the source code, especially those that are directly applied to sensitive data. All cryptographic operations should use standard cryptographic APIs for Android and iOS (we'll write about those in more detail in the platform-specific chapters). Any cryptographic operations that don't invoke standard routines from known providers should be closely inspected. Pay close attention to standard algorithms that have been modified. Remember that encoding isn't the same as encryption! Always investigate further when you find bit manipulation operators like XOR (exclusive OR).
-At all implementations of cryptography, you need to ensure that the following always takes place:
+In all implementations of cryptography, you need to ensure that the following always takes place:
-- Worker keys (like intermediary/derived keys in AES/DES/Rijndael) are properly removed from memory after consumption or in case of error.
+- Working keys (like intermediary/derived keys in AES/DES/Rijndael) are properly removed from memory after consumption or in case of error.
- The inner state of a cipher should be removed from memory as soon as possible.
-### Inadequate AES Configuration
+### Improper Encryption
Advanced Encryption Standard (AES) is the widely accepted standard for symmetric encryption in mobile apps. It's an iterative block cipher that is based on a series of linked mathematical operations. AES performs a variable number of rounds on the input, each of which involve substitution and permutation of the bytes in the input block. Each round uses a 128-bit round key which is derived from the original AES key.
As of this writing, no efficient cryptanalytic attacks against AES have been discovered. However, implementation details and configurable parameters such as the block cipher mode leave some margin for error.
-#### Weak Block Cipher Mode
+#### Broken Block Cipher Modes
Block-based encryption is performed upon discrete input blocks (for example, AES has 128-bit blocks). If the plaintext is larger than the block size, the plaintext is internally split up into blocks of the given input size and encryption is performed on each block. A block cipher mode of operation (or block mode) determines if the result of encrypting the previous block impacts subsequent blocks.
-[ECB (Electronic Codebook)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_%28ECB%29 "Electronic Codebook (ECB)") divides the input into fixed-size blocks that are encrypted separately using the same key. If multiple divided blocks contain the same plaintext, they will be encrypted into identical ciphertext blocks which makes patterns in data easier to identify. In some situations, an attacker might also be able to replay the encrypted data.
+Avoid using the [ECB (Electronic Codebook)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_%28ECB%29 "Electronic Codebook (ECB)") mode. ECB divides the input into fixed-size blocks that are encrypted separately using the same key. If multiple divided blocks contain the same plaintext, they will be encrypted into identical ciphertext blocks which makes patterns in data easier to identify. In some situations, an attacker might also be able to replay the encrypted data.
-Verify that Cipher Block Chaining (CBC) mode is used instead of ECB. In CBC mode, plaintext blocks are XORed with the previous ciphertext block. This ensures that each encrypted block is unique and randomized even if blocks contain the same information. Please note that it is best to combine CBC with an HMAC and/or ensure that no errors are given such as "Padding error", "MAC error", "decryption failed" in order to be more resistant to a padding oracle attack.
+For new designs, prefer authenticated encryption with associated data (AEAD) modes such as Galois/Counter Mode (GCM) or Counter with CBC-MAC (CCM), as these provide both confidentiality and integrity. If GCM or CCM are not available, Cipher Block Chaining (CBC) mode is better than ECB, but should be combined with an HMAC and/or ensure that no errors are given such as "Padding error", "MAC error", or "decryption failed" to be more resistant to padding oracle attacks. In CBC mode, plaintext blocks are XORed with the previous ciphertext block, ensuring that each encrypted block is unique and randomized even if blocks contain the same information.
-When storing encrypted data, we recommend using a block mode that also protects the integrity of the stored data, such as Galois/Counter Mode (GCM). The latter has the additional benefit that the algorithm is mandatory for each TLSv1.2 implementation, and thus is available on all modern platforms.
+When storing encrypted data, we recommend using a block mode that also protects the integrity of the stored data, such as Galois/Counter Mode (GCM). The latter has the additional benefit that the algorithm is mandatory for each TLSv1.2 implementation, and thus is available on all modern platforms. To protect the integrity and authenticity of the data using CBC mode, it is recommended to combine the techniques of the Counter (CTR) mode and the Cipher Block Chaining-Message Authentication Code (CBC-MAC) into what is called CCM Mode ([NIST, 2004](https://csrc.nist.gov/pubs/sp/800/38/c/upd1/final "NIST: Recommendation for Block Cipher Modes of Operation: the CCM Mode for Authentication and Confidentiality")).
For more information on effective block modes, see the [NIST guidelines on block mode selection](https://csrc.nist.gov/groups/ST/toolkit/BCM/modes_development.html "NIST Modes Development, Proposed Modes").
@@ -146,7 +197,11 @@ CBC, OFB, CFB, PCBC, GCM mode require an initialization vector (IV) as an initia
Pay attention to cryptographic libraries used in the code: many open source libraries provide examples in their documentations that might follow bad practices (e.g. using a hardcoded IV). A popular mistake is copy-pasting example code without changing the IV value.
-#### Initialization Vectors in stateful operation modes
+#### Using the Same Key for Encryption and Authentication
+
+One common mistake is to reuse the same key for CBC encryption and CBC-MAC. Reuse of keys for different purposes is generally not recommended, but in the case of CBC-MAC the mistake can lead to a MitM attack (["CBC-MAC", 2024.10.11](https://en.wikipedia.org/wiki/CBC-MAC "Wikipedia: CBC-MAC")).
+
+#### Initialization Vectors in Stateful Operation Modes
Please note that the usage of IVs is different when using CTR and GCM mode in which the initialization vector is often a counter (in CTR combined with a nonce). So here using a predictable IV with its own stateful model is exactly what is needed. In CTR you have a new nonce plus counter as an input to every new block operation. For example: for a 5120 bit long plaintext: you have 20 blocks, so you need 20 input vectors consisting of a nonce and counter. Whereas in GCM you have a single IV per cryptographic operation, which should not be repeated with the same key. See section 8 of the [documentation from NIST on GCM](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode and GMAC") for more details and recommendations of the IV.
@@ -164,7 +219,7 @@ Therefore it is best to consider the following, if keys are still needed at the
- **Keys in a Remote Server**: you can use remote Key vaults such as Amazon KMS or Azure Key Vault. For some use cases, developing an orchestration layer between the app and the remote resource might be a suitable option. For instance, a serverless function running on a Function as a Service (FaaS) system (e.g. AWS Lambda or Google Cloud Functions) which forwards requests to retrieve an API key or secret. There are other alternatives such as Amazon Cognito, Google Identity Platform or Azure Active Directory.
- **Keys inside Secure Hardware-backed Storage**: make sure that all cryptographic actions and the key itself remain in the Trusted Execution Environment (e.g. use [Android Keystore](https://developer.android.com/training/articles/keystore.html "Android keystore system")) or [Secure Enclave](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave "Storing Keys in the Secure Enclave") (e.g. use the Keychain). Refer to the [Android Data Storage](0x05d-Testing-Data-Storage.md#storing-keys-using-hardware-backed-android-keystore) and [iOS Data Storage](0x06d-Testing-Data-Storage.md#the-keychain) chapters for more information.
- **Keys protected by Envelope Encryption**: If keys are stored outside of the TEE / SE, consider using multi-layered encryption: an _envelope encryption_ approach (see [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#encrypting-stored-keys "OWASP Cryptographic Storage Cheat Sheet: Encrypting Stored Keys"), [Google Cloud Key management guide](https://cloud.google.com/kms/docs/envelope-encryption?hl=en "Google Cloud Key management guide: Envelope encryption"), [AWS Well-Architected Framework guide](https://docs.aws.amazon.com/wellarchitected/latest/financial-services-industry-lens/use-envelope-encryption-with-customer-master-keys.html "AWS Well-Architected Framework")), or [a HPKE approach](https://tools.ietf.org/html/draft-irtf-cfrg-hpke-08 "Hybrid Public Key Encryption") to encrypt data encryption keys with key encryption keys.
-- **Keys in Memory**: make sure that keys live in memory for the shortest time possible and consider zeroing out and nullifying keys after successful cryptographic operations, and in case of error. For general cryptocoding guidelines, refer to [Clean memory of secret data](https://github.com/veorq/cryptocoding#clean-memory-of-secret-data/ "The Cryptocoding Guidelines by @veorq: Clean memory of secret data").
+- **Keys in Memory**: make sure that keys live in memory for the shortest time possible and consider zeroing out and nullifying keys after successful cryptographic operations, and in case of error. Note: In some languages and platforms (such as those with garbage collection or memory management optimizations), reliably zeroing memory may not be possible, as the runtime may move or copy memory or delay actual erasure. For general cryptocoding guidelines, refer to [Clean memory of secret data](https://github.com/veorq/cryptocoding#clean-memory-of-secret-data/ "The Cryptocoding Guidelines by @veorq: Clean memory of secret data").
Note: given the ease of memory dumping, never share the same key among accounts and/or devices, other than public keys used for signature verification or encryption.
From dbbd367c977502eac58fd9e6993def645ff80692 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Wed, 16 Jul 2025 15:34:07 +0200
Subject: [PATCH 02/15] Add back intro
---
Document/0x04g-Testing-Cryptography.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index ed5ea97038c..940f2ef9b0b 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -149,6 +149,8 @@ When using a password hashing algorithm as a KDF, also ensure to choose an appro
### Improper Random Number Generation
+A common weakness in mobile apps is the improper use of random number generators. Regular Pseudo-Random Number Generators (PRNGs), while sufficient for general use, are not designed for cryptographic purposes. When used to generate keys, tokens, or other security-critical values, they can make systems vulnerable to prediction and attack.
+
It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (PRNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. Cryptographically secure PRNGs (CSPRNG) generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced).
PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
From 71646061f53bf6952dc589a6c4feaa15665dd9f8 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Wed, 16 Jul 2025 15:51:26 +0200
Subject: [PATCH 03/15] Remove unfinished tail
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 940f2ef9b0b..2b2fa4a9c92 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -155,7 +155,7 @@ It is fundamentally impossible to produce truly random numbers on any determinis
PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
-Mobile SDKs offer standard implementations of PRNG algorithms that produce numbers with sufficient artificial randomness. We'll introduce the available APIs in the Android and iOS-
+Mobile SDKs offer standard implementations of PRNG algorithms that produce numbers with sufficient artificial randomness.
### Improper Hashing
From fc8f1801e94560162806ffcae05976e473752ba8 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Wed, 16 Jul 2025 15:53:22 +0200
Subject: [PATCH 04/15] Remove unfinished tail
---
Document/0x04g-Testing-Cryptography.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 2b2fa4a9c92..1ce52f74cf9 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -155,8 +155,6 @@ It is fundamentally impossible to produce truly random numbers on any determinis
PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
-Mobile SDKs offer standard implementations of PRNG algorithms that produce numbers with sufficient artificial randomness.
-
### Improper Hashing
Using the wrong hash function for a given purpose can compromise both security and data integrity. Each hash function is designed with specific use cases in mind, and applying it incorrectly introduces risk.
From 1d87380a40ae3cbf750c528c16eb1a5746e463a7 Mon Sep 17 00:00:00 2001
From: sydseter
Date: Mon, 25 Aug 2025 09:53:40 +0200
Subject: [PATCH 05/15] #3379 Adding an extra line according to review comments
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 1ce52f74cf9..d583cc52e92 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -119,7 +119,7 @@ Secret keys must be stored in secure device storage whenever symmetric cryptogra
### Improper Key Derivation Functions
When discussing key derivation functions (KDFs) in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password storage. This chapter focuses primarily on KDF in the context of cryptographic key derivation, rather than 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 derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF).
+KDFs derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF). While it’s primarily used for password hashing, it's also used for master key derivation, key stretching and Diffie-Hellman Key Exchange.
Different KDFs are suitable for different tasks such as:
From d3a5ead9b77f64f64e9a8edbae7babff7ad21ee7 Mon Sep 17 00:00:00 2001
From: sydseter
Date: Mon, 25 Aug 2025 09:56:48 +0200
Subject: [PATCH 06/15] Remove extra line
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index d583cc52e92..1ce52f74cf9 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -119,7 +119,7 @@ Secret keys must be stored in secure device storage whenever symmetric cryptogra
### Improper Key Derivation Functions
When discussing key derivation functions (KDFs) in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password storage. This chapter focuses primarily on KDF in the context of cryptographic key derivation, rather than 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 derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF). While it’s primarily used for password hashing, it's also used for master key derivation, key stretching and Diffie-Hellman Key Exchange.
+KDFs derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF).
Different KDFs are suitable for different tasks such as:
From ea4cba8fc5c9443f5ea4f1b8710b1d80f232d8b3 Mon Sep 17 00:00:00 2001
From: sydseter
Date: Fri, 29 Aug 2025 01:20:29 +0200
Subject: [PATCH 07/15] Add pointer regarding HKDF and Password based KDFs
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 1ce52f74cf9..8e9237d9ad7 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -144,7 +144,7 @@ Some hash functions that have one or more of these desired properties include [s
Note that using these functions can have an impact on performance, so they require special consideration to avoid denial-of-service attacks. However, their configurability provides finer control over how much CPU and memory is used, so it could be adjusted to suit the environment's needs. In the case where CPU and memory performance is a challenge try adjusting desired bit-length of the derived key instead of increasing the iteration account (e.g using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible by brute-force attacks, but should be acceptable as long as you keep yourself within recommended guidelines.
Unfortunately, "brute-force" attacks are quite liable to succeed where users selects passwords and pins with none or with too little entropy than what is required for cryptographic keys. Therefore, ensure that passwords and pins aren't directly passed into a HKDF. The key that is input 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 key-derivation functions 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")).
-In cases where the input is user-controlled, use password hashing algorithm like Argon2, scrypt, bcrypt or PBKDF2 as a key derivation function to provide a sufficient level of computational effort.
+In cases where the input is user-controlled, use password hashing algorithm like Argon2, scrypt, bcrypt or PBKDF2 as a key derivation function to provide a sufficient level of computational effort. Do not use a HKDF or any other type of integrity based hashing algorithm like MD5, SHA-1, SHA-2 or even 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 random generated keys.
When using a password hashing algorithm as a KDF, also ensure to choose an appropriate iteration count that can provide sufficient computational efforts. Meaning that they make 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 implementation algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [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 recommendation on iteration count when using key derivation functions using Argon2, scrypt, bcrypt or PBKDF2.
### Improper Random Number Generation
From 9579c334a9bd5a44fd4d047bed3322c8e9827e9f Mon Sep 17 00:00:00 2001
From: sydseter
Date: Fri, 29 Aug 2025 01:25:51 +0200
Subject: [PATCH 08/15] Correct grammer
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 8e9237d9ad7..432d4d1c71f 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -144,7 +144,7 @@ Some hash functions that have one or more of these desired properties include [s
Note that using these functions can have an impact on performance, so they require special consideration to avoid denial-of-service attacks. However, their configurability provides finer control over how much CPU and memory is used, so it could be adjusted to suit the environment's needs. In the case where CPU and memory performance is a challenge try adjusting desired bit-length of the derived key instead of increasing the iteration account (e.g using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible by brute-force attacks, but should be acceptable as long as you keep yourself within recommended guidelines.
Unfortunately, "brute-force" attacks are quite liable to succeed where users selects passwords and pins with none or with too little entropy than what is required for cryptographic keys. Therefore, ensure that passwords and pins aren't directly passed into a HKDF. The key that is input 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 key-derivation functions 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")).
-In cases where the input is user-controlled, use password hashing algorithm like Argon2, scrypt, bcrypt or PBKDF2 as a key derivation function to provide a sufficient level of computational effort. Do not use a HKDF or any other type of integrity based hashing algorithm like MD5, SHA-1, SHA-2 or even 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 random generated keys.
+If the input is user-controlled, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 is used as a key derivation function 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 to choose an appropriate iteration count that can provide sufficient computational efforts. Meaning that they make 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 implementation algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [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 recommendation on iteration count when using key derivation functions using Argon2, scrypt, bcrypt or PBKDF2.
### Improper Random Number Generation
From be359801874caac9793293bf2176cfb55e516499 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Sun, 31 Aug 2025 20:35:15 +0200
Subject: [PATCH 09/15] Update Document/0x04g-Testing-Cryptography.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 432d4d1c71f..068a6083e29 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -133,7 +133,7 @@ Different KDFs are suitable for different tasks such as:
- Password storage:
- In order to ensure attacker's can't use a stolen password even in the event of a data breach, passwords are stored as hashes computed through a computationally intensive KDF. The ideal password storage's KDF should be demanding on both computational and memory resources.
-Source: ([Wikipedia, 2025.02.21"](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function"))
+Source: ([Wikipedia, 2025.02.21](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function"))
When using a KDF for cryptographic operations always ensure to use a recommended and approved KDF properly according to the latest recommendations and the software provider's documentation. E.g Only using a key derivation functions that is constructed from hashes against which no non-trivial pre-image or length-extension attacks are known and where attacking the key derivation function directly is infeasible. Using user-supplied input together with HKDF will make it easy for password crackers to execute a preimage attack.
From c424a82403e6113ac970d5258d21e83b1a9250e8 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Sun, 31 Aug 2025 20:35:37 +0200
Subject: [PATCH 10/15] Update Document/0x04g-Testing-Cryptography.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 068a6083e29..6a65ce45e55 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -124,7 +124,7 @@ KDFs derive bytes suitable for cryptographic operations from passwords or other
Different KDFs are suitable for different tasks such as:
- Cryptographic key derivation:
- - Together with a non-secret parameter to derive one or more keys from a common secret value. Also known as known as "key diversification"
+ - Together with a non-secret parameter to derive one or more keys from a common secret value. Also known as "key diversification"
- As components of multiparty key-agreement protocols (e.g: [KDF1](https://en.wikipedia.org/wiki/IEEE_P1363)).
- To derive keys from secret passwords or passphrases.
- To derive keys of different length from the ones provided (e.g: [PBKDF2HMAC](https://en.wikipedia.org/wiki/PBKDF2) or [HKDF](https://en.wikipedia.org/wiki/HKDF)).
From e5a2dd5d35bc97b03df6ca813b1be8ca12faf033 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Mon, 3 Nov 2025 09:57:17 +0100
Subject: [PATCH 11/15] Update Document/0x04g-Testing-Cryptography.md
Co-authored-by: Dionysis Lorentzos
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 6a65ce45e55..b079c8bc45c 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -151,7 +151,7 @@ When using a password hashing algorithm as a KDF, also ensure to choose an appro
A common weakness in mobile apps is the improper use of random number generators. Regular Pseudo-Random Number Generators (PRNGs), while sufficient for general use, are not designed for cryptographic purposes. When used to generate keys, tokens, or other security-critical values, they can make systems vulnerable to prediction and attack.
-It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (PRNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. Cryptographically secure PRNGs (CSPRNG) generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced).
+It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-Random Number Generators (PRNGs) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies depending on the algorithm used. Cryptographically secure PRNGs (CSPRNGs) generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g., it is statistically infeasible to predict the next number produced).
PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
From 12ce2b3d6874c890bd0f2db5dcaebfdc8db5c235 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Mon, 3 Nov 2025 09:57:35 +0100
Subject: [PATCH 12/15] Update Document/0x04g-Testing-Cryptography.md
Co-authored-by: Dionysis Lorentzos
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index b079c8bc45c..de70f9b6eed 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -153,7 +153,7 @@ A common weakness in mobile apps is the improper use of random number generators
It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-Random Number Generators (PRNGs) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies depending on the algorithm used. Cryptographically secure PRNGs (CSPRNGs) generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g., it is statistically infeasible to predict the next number produced).
-PRNGs can be vulnerable when developers use a regular PRNG for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a cryptographically secure pseudo-random number generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
+PRNGs can be vulnerable when developers use them for cryptographic purposes, instead of a cryptographically secure PRNG (["Cryptographically secure pseudorandom number generator", 2025.01.31](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator "Wikipedia: Cryptographically secure pseudorandom number generator")). All random numbers and strings which are intended to be non-guessable must be generated using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) and have at least 128 bits of entropy. Note that UUIDs do not meet this condition.
### Improper Hashing
From b83398c4bf1ff3d79847a9f9351565bd7c78d984 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Mon, 3 Nov 2025 10:07:30 +0100
Subject: [PATCH 13/15] Revise KDF section for clarity and recommendations
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.
---
Document/0x04g-Testing-Cryptography.md | 46 ++++++++++----------------
1 file changed, 18 insertions(+), 28 deletions(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index de70f9b6eed..468a0c68946 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -118,34 +118,24 @@ Secret keys must be stored in secure device storage whenever symmetric cryptogra
### Improper Key Derivation Functions
-When discussing key derivation functions (KDFs) in the context of mobile applications, we are usually referring to cryptographic key derivation rather than password storage. This chapter focuses primarily on KDF in the context of cryptographic key derivation, rather than 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 derive bytes suitable for cryptographic operations from passwords or other data sources using a pseudorandom function (PRF).
-
-Different KDFs are suitable for different tasks such as:
-
-- Cryptographic key derivation:
- - Together with a non-secret parameter to derive one or more keys from a common secret value. Also known as "key diversification"
- - As components of multiparty key-agreement protocols (e.g: [KDF1](https://en.wikipedia.org/wiki/IEEE_P1363)).
- - To derive keys from secret passwords or passphrases.
- - To derive keys of different length from the ones provided (e.g: [PBKDF2HMAC](https://en.wikipedia.org/wiki/PBKDF2) or [HKDF](https://en.wikipedia.org/wiki/HKDF)).
- - [Key stretching](https://en.wikipedia.org/wiki/Key_stretching) and [key strengthening](https://en.wikipedia.org/wiki/Key_derivation_function#Key_stretching_and_key_strengthening).
-
-- Password storage:
- - In order to ensure attacker's can't use a stolen password even in the event of a data breach, passwords are stored as hashes computed through a computationally intensive KDF. The ideal password storage's KDF should be demanding on both computational and memory resources.
-
-Source: ([Wikipedia, 2025.02.21](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function"))
-
-When using a KDF for cryptographic operations always ensure to use a recommended and approved KDF properly according to the latest recommendations and the software provider's documentation. E.g Only using a key derivation functions that is constructed from hashes against which no non-trivial pre-image or length-extension attacks are known and where attacking the key derivation function directly is infeasible. Using user-supplied input together with HKDF will make it easy for password crackers to execute a preimage attack.
-
-Choose a KDF that use 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 for a brute force attack compared to intentionally-fast functions. For example, rainbow table attacks can become infeasible due to the high computing overhead. Finally, since computing power gets faster and cheaper over time, the technique can be reconfigured to increase the workload without forcing an entire 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 about which of these is the most effective, they are all stronger than using salts with hash functions with very little computing overhead.
-
-Note that using these functions can have an impact on performance, so they require special consideration to avoid denial-of-service attacks. However, their configurability provides finer control over how much CPU and memory is used, so it could be adjusted to suit the environment's needs. In the case where CPU and memory performance is a challenge try adjusting desired bit-length of the derived key instead of increasing the iteration account (e.g using HMAC-SHA512 instead of HMAC-SHA256). This might make the KDF more susceptible by brute-force attacks, but should be acceptable as long as you keep yourself within recommended guidelines.
-
-Unfortunately, "brute-force" attacks are quite liable to succeed where users selects passwords and pins with none or with too little entropy than what is required for cryptographic keys. Therefore, ensure that passwords and pins aren't directly passed into a HKDF. The key that is input 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 key-derivation functions 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")).
-If the input is user-controlled, a password hashing algorithm like Argon2, scrypt, bcrypt, or PBKDF2 is used as a key derivation function 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 to choose an appropriate iteration count that can provide sufficient computational efforts. Meaning that they make 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 implementation algorithms recognized by [Password Hashing Competition (PHC)](https://password-hashing.net/ "PHC") like [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 recommendation on iteration count when using key derivation functions using Argon2, scrypt, bcrypt or PBKDF2.
+Different Key Derivation Functions (KDFs) are suitable for various tasks, most commonly known for the following two:
+- Key Derivation: the generation of keys from secret passwords or passphrases.
+- 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).
+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:
+- 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.
+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 adjusting 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.
+Further read:
+- [NIST SP 800-132: Recommendation for Password-Based Key Derivation](https://csrc.nist.gov/pubs/sp/800/132/final)
+- [Wikipedia, 2025.02.21](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function")
+- [KDF1](https://en.wikipedia.org/wiki/IEEE_P1363)
+- [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)
+- [HKDF](https://en.wikipedia.org/wiki/HKDF)
### Improper Random Number Generation
From ddd78e54f923d4018a66fe6f7cf4c967b3ba59b9 Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Mon, 3 Nov 2025 10:10:22 +0100
Subject: [PATCH 14/15] Update KDF and password hashing recommendations
Clarified recommendations for using KDFs and password hashing algorithms, including iteration counts and suitable algorithms.
---
Document/0x04g-Testing-Cryptography.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index 468a0c68946..edd8572ab66 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -127,7 +127,7 @@ In short, we recommend:
- 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.
-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 adjusting 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 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.
Further read:
From 8c78977546a769dfe307c9bc928bc16b057b4c5f Mon Sep 17 00:00:00 2001
From: Uncle Joe <1244005+sydseter@users.noreply.github.com>
Date: Mon, 3 Nov 2025 13:41:38 +0100
Subject: [PATCH 15/15] Fix linting
---
Document/0x04g-Testing-Cryptography.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md
index edd8572ab66..29f99b59865 100644
--- a/Document/0x04g-Testing-Cryptography.md
+++ b/Document/0x04g-Testing-Cryptography.md
@@ -119,18 +119,24 @@ Secret keys must be stored in secure device storage whenever symmetric cryptogra
### Improper Key Derivation Functions
Different Key Derivation Functions (KDFs) are suitable for various tasks, most commonly known for the following two:
+
- Key Derivation: the generation of keys from secret passwords or passphrases.
- 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).
+
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:
-- 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.
+
+- 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.
+
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.
+
Further read:
+
- [NIST SP 800-132: Recommendation for Password-Based Key Derivation](https://csrc.nist.gov/pubs/sp/800/132/final)
- [Wikipedia, 2025.02.21](https://en.wikipedia.org/wiki/Key_derivation_function "Key derivation function")
- [KDF1](https://en.wikipedia.org/wiki/IEEE_P1363)