rfc:improve_hash_hkdf_pramater

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:improve_hash_hkdf_pramater [2017/02/05 02:00] yohgakirfc:improve_hash_hkdf_pramater [2017/02/05 06:30] yohgaki
Line 8: Line 8:
 ===== Introduction ===== ===== Introduction =====
  
-HKDF is informational internet standard defined by [[https://tools.ietf.org/html/rfc5869|RFC 5869]]. HKDF is designed to generate secure key for encryption/validation/authentication/etc from other key information such as output from hash_password(), API KEY, etc. hash_hkdf() is added to master without RFC already. It has following signature currently.+HKDF is informational internet standard defined by [[https://tools.ietf.org/html/rfc5869|RFC 5869]]. HKDF is designed to generate secure key for encryption/validation/authentication/etc from other key information such as output from hash_password(), API KEY, etc. This PHP RFC will not explain HKDF in detail, please refer to RFC 5869 or other references for details. 
 + 
 +  * https://tools.ietf.org/html/rfc5869 
 +  * https://en.wikipedia.org/wiki/Key_derivation_function 
 +  * https://en.wikipedia.org/wiki/HKDF 
 + 
 +hash_hkdf() is added to master without PHP RFC already. It has following signature currently.
  
 <code> <code>
Line 16: Line 22:
 Issue is parameter order and handling.  Issue is parameter order and handling. 
  
-RFC 5869 notes for HKDF users. It states,+RFC 5869 "Notes for HKDF Users" states,
  
 <blockquote>3.1.  To Salt or not to Salt <blockquote>3.1.  To Salt or not to Salt
  
-HKDF is defined to operate with and without random salt.  This is+**HKDF is defined to operate with and without random salt.  This is
 done to accommodate applications where a salt value is not available. done to accommodate applications where a salt value is not available.
-We stress, however, that the use of salt adds significantly to the +**We stress, however, that the use of **salt adds significantly to the 
-strength of HKDF, ensuring independence between different uses of the+strength of HKDF**, ensuring independence between different uses of the
 hash function, supporting "source-independent" extraction, and hash function, supporting "source-independent" extraction, and
 strengthening the analytical results that back the HKDF design. strengthening the analytical results that back the HKDF design.
Line 56: Line 62:
 </blockquote> </blockquote>
  
-As you can see from the RFC, it states even weak salt can make HKDF result much stronger than without salt. Thus users should supply salt whenever it is possible even if it can be omitted. HKDF is designed to be stronger with salt. +<blockquote> 
 +3.2.  The 'info' Input to HKDF 
 + 
 +While the 'info' value is optional in the definition of HKDF, **it is 
 +often of great importance in applications**.  Its main objective is to 
 +bind the derived key material to application- and context-specific 
 +information.  For example, 'info' may contain a protocol number, 
 +algorithm identifiers, user identities, etc.  In particular, it may 
 +prevent the derivation of the same keying material for different 
 +contexts (when the same input key material (IKM) is used in such 
 +different contexts).  It may also accommodate additional inputs to 
 +the key expansion part, if so desired (e.g., an application may want 
 +to bind the key material to its length L, thus making L part of the 
 +'info' field).  There is one technical requirement from 'info': it 
 +should be independent of the input key material value IKM. 
 +</blockquote> 
 + 
 +As you can see from the RFC, it states even weak "saltcan make HKDF result much stronger than without "salt". Thus users should supply "saltwhenever it is possible even if it can be omitted. HKDF is designed to be stronger with "salt".  
 + 
 +The RFC described "info" parameter in following section. It refers as "often of great importance in applications". This PHP RFC describes how it could be important to applications in following section. 
 + 
 +As the RFC 3.1 states "HKDF is defined to operate with and without random salt.  This is done to accommodate applications where a salt value is not available." which means "If salt value can be used, use it".  
 + 
 +The RFC describes "salt" as "**salt adds significantly to the strength of HKDF**" while "info" as "**it is often of great importance in applications**". Both parameters are important, but not equally. It is obvious from the RFC "salt" is more important. 
  
 ==== hash_hkdf() applications ===== ==== hash_hkdf() applications =====
  
-This RFC only describes 2 examples, but there are many HKDF application. e.g. Object Store, etc. Developers must consider salt use for better security rather than omitting salt without proper consideration.+Typical PHP HKDF application can be used with "salt"This PHP RFC only describes 2 examples, but there are many PHP HKDF applications that can/should/must use with salt. e.g. Object Store, Per session encryption, etc. Developers must consider salt use for better security rather than omitting salt without proper consideration
 + 
 +Please note that HKDF is designed for super secret key like master key for critical systems. There is nothing wrong to use with hash_password() generated string as input key.
  
 === Per user data encryption === === Per user data encryption ===
  
-  - Get the password hash generated by hash_password() for the user +  - Get the secret password hash generated by hash_password() for the user.   $ikm 
-  - Get application secret salt stored in secure place. i.g. $_ENV +  - Get application secret salt stored in secure place. e.g. $_ENV   $salt 
-  - Generate HKDF hash value with 1 and 2 by hash_hkdf()+  - Generate HKDF hash value with 1 and 2. <nowiki> hash_hkdf('sha256', $ikm, 0, '', $salt</nowiki>
   - Encrypt the user data with the key from 3   - Encrypt the user data with the key from 3
  
Line 74: Line 106:
  
 See also **Security Note** section blow. The same technique can be used for per user encryption key. See also **Security Note** section blow. The same technique can be used for per user encryption key.
 +
 +Other way to encrypt per user
 +
 +  - Get system shared secret encryption key from secure place. $ikm
 +  - Get user ID which is unique in the system. $info
 +  - Generate HKDF hash value 1 and 2. <nowiki>hash_hkdf('sha256', $ikm, 0, $info)</nowiki>
 +
 +
 +Note that both method uses "secret" information for $ikm. However, there is notable difference between these 2. This method uses only 1 secret key (encryption key) and info (user ID) is known to public, 1 stolen key allows attackers to decrypt all encrypted data while previous method requires 2 secret information(password hash and secret salt) to attack. (In addition, attackers have to steal all users password hash)
 +
 +There are many usages other than these two. Users can choose appropriate method for their needs.
 +
  
 === CSRF token === === CSRF token ===
Line 80: Line 124:
  
 Setting up CSRF token Setting up CSRF token
-  - Get expiration timestamp as salt +  - Get expiration timestamp. ($salt) 
-  - Generate HKDF value with 1 and session ID +  - Generate HKDF value with 1 and session ID ($ikm).  <nowiki>hash_hkdf('sha256', $ikm, 0, '', $salt)</nowiki> 
-  - Send key from 2 and timestamp from 1 to browser as CSRF token+  - Send key from 2 and timestamp from 1 to browser as CSRF token.
  
 Verifying CSRF token Verifying CSRF token
-  - Get HKDF key and timestamp(salt) value from request +  - Get HKDF key and timestamp($salt) value from request. 
-  - Check if timestamp is not expired +  - Check if timestamp is not expired. 
-  - Generate HKDF value session ID and timestamp(salt) +  - Generate HKDF value from session ID($ikm) and timestamp($salt). <nowiki> hash_hkdf('sha256', $ikm, 0, '', $salt)</nowiki> 
-  - Compare HKDF value sent by browser and server generated HKDF value if it matches+  - Compare HKDF value sent by browser and server generated HKDF value if it matches.
  
 Secure CSRF token expiration can be defined with this method regardless of session ID lifetime. i.e. You can set short CSRF token expiration securely. Secure CSRF token expiration can be defined with this method regardless of session ID lifetime. i.e. You can set short CSRF token expiration securely.
Line 98: Line 142:
 https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_Expiration https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_Expiration
  
-Therefore, use of session ID as CSRF token key source is not recommended. You are better to use separate key for CSRF token generation in $_SESSION. e.g. $_SESSION['CSRF_TOKEN_IKM'] = session_create_id(); Use secret $_SESSION['CSRF_TOKEN_IKM'] for HKDF key generation where above example use session ID. With this method, you can generate secure HKDF CSRF token even when session ID is regenerated with your defined token expiration time. +Therefore, use of session ID as CSRF token key source is not recommended. You are better to use separate key for CSRF token generation in $_SESSION. e.g. $_SESSION['CSRF_TOKEN_IKM'] = session_create_id(); Use secret $_SESSION['CSRF_TOKEN_IKM'] for HKDF key generation where above example uses session ID. With this method, you can generate secure HKDF CSRF token even when session ID is regenerated with your defined token expiration time. 
  
 ==Use of info parameter== ==Use of info parameter==
Line 106: Line 150:
 ===== Proposal ===== ===== Proposal =====
  
-Internet RFC clearly recommends "salt" value whenever it is possible+Internet RFC clearly recommends "salt" value whenever it is possible. **Users are likely to omit optional parameters without consideration, especially the last one when there are less likely used parameters.**
  
-Change hash_hkdf() from+Change hash_hkdf() signature from
  
 <code> <code>
Line 118: Line 162:
 <code> <code>
 string hash_hkdf(string algo, string ikm, string salt [, string info = '']) string hash_hkdf(string algo, string ikm, string salt [, string info = ''])
- - Set empty string to use without salt.+ - Set NULL to use without salt, raise exception for empty string.
  - Note: length is only used for internal execution optimization. It will set to proper value according to inputs.  - Note: length is only used for internal execution optimization. It will set to proper value according to inputs.
 </code> </code>
  
 From user perspective, "salt" and "info" parameters can be used interchangeably. However, it would be good idea to follow RFC 5869 semantics.  From user perspective, "salt" and "info" parameters can be used interchangeably. However, it would be good idea to follow RFC 5869 semantics. 
-Unlike "info" which could be an optional, "salt" cannot be an optional with expiration enabled keys. This kind of expiration is common. e.g. Amazon AWS S3 uses HKDF with expiration to allow access to objects. +Unlike "info" which could be an optional in many cases, "salt" cannot be an optional with expiration enabled keys for instance. This kind of expiration is common. e.g. Amazon AWS S3 uses HKDF with expiration to allow access to objects. 
  
-Typical PHP applications that need HKDF can use (or should use) salt for security reasons as examples above. Users should consider if salt can be used or not. If use of salt is impossible, then it should set to be empty. They shouldn't omit salt without consideration which could lead serious security issue. Therefore, salt is better to be required parameter. +Typical PHP applications that need HKDF can use (or should use) salt for security reasons as examples above. Users should consider if salt can be used or not. If use of salt is impossible, then it should set to be empty. Users shouldn't omit salt blindly. It could lead serious security issue. Therefore, salt is better to be required parameter because typical PHP applications can supply salt.
  
 ===== Discussions ===== ===== Discussions =====
rfc/improve_hash_hkdf_pramater.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1