rfc:secure_serialization

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
rfc:secure_serialization [2015/12/30 19:38] yohgakirfc:secure_serialization [2018/03/01 23:18] (current) – RFC is Under Discussion carusogabriel
Line 3: Line 3:
   * Date: 2015-12-30   * Date: 2015-12-30
   * Author: Yasuo Ohgaki <yohgaki@php.net>   * Author: Yasuo Ohgaki <yohgaki@php.net>
-  * Status: Draft+  * Status: Under Discussion
   * First Published at: http://wiki.php.net/rfc/secure_serialization   * First Published at: http://wiki.php.net/rfc/secure_serialization
  
Line 20: Line 20:
 ===== Proposal ===== ===== Proposal =====
  
-  * Add secure_serialize() and secure_unserialize() supports message authentication code generation/validation and expiration.+  * Add serialize_mhac() and unserialize_mhac() supports message authentication code generation/validation and expiration.
  
 <code php> <code php>
-  string secure_serialize(mixed $data_to_be_serialized , string $secret_key [, int $ttl=1800 [,bool $session_only=TRUE]]) +  string serialize_mhac(mixed $data_to_be_serialized , string $secret_key [, int $ttl=1800 [,bool $session_only=TRUE]]) 
-  mixed secure_unserialize(mixed $data_to_be_unserialized , string $secret_key='')+  mixed unserialize_mhac(mixed $data_to_be_unserialized , mixed $secret_keys)
 </code> </code>
  
  
-==== How secure_serialize() works ====+==== How serialize_mhac() works ====
  
 Pseudo code Pseudo code
 <code php> <code php>
-function secure_serialize(string $data_to_be_serialized, string $secret_key, int $ttl, bool $session_only = TRUE) : string {+function secure_serialize(string $data_to_be_serialized, string $secret_key, int $ttl=1800, bool $session_only = TRUE) : string {
   if (strlen($secret_key) < 32) {   if (strlen($secret_key) < 32) {
     trigger_error('Too short secret key');     trigger_error('Too short secret key');
     return FALSE;     return FALSE;
   }   }
-  if ($ttl <0) {+  if ($ttl < 0) {
     trigger_error('Invalid TTL');     trigger_error('Invalid TTL');
     return FALSE;     return FALSE;
   }   }
-  $ttl = time() + $ttl; +  $ttl = $ttl ? time() + $ttl : 0
   $session_only = $session_only ? TRUE : FALSE;   $session_only = $session_only ? TRUE : FALSE;
   // Use random key to randomize $mac   // Use random key to randomize $mac
Line 47: Line 47:
      
   $serialized_data = serialize($data_to_be_serialized);   $serialized_data = serialize($data_to_be_serialized);
 +  $keys = is_array($secret_key) ?: array(secret_key);
 +  
   if ($session_only && session_id()) {   if ($session_only && session_id()) {
     // Session ID is hashed by SHA256 to avoid session ID exposure.     // Session ID is hashed by SHA256 to avoid session ID exposure.
-    $mac = sha256($secret_key.$ttl.$key.sha256($secret_key.session_id()).$serialized_data); +    $mac = hash_hmac( 
-    return serialize['mac'=>$mac, 'ttl'=>$ttl, 'key'=>$key, 'id'=>sha256($secret_key.session_id()),  'data'=>$serialized_data];+      'sha256', 
 +      $ttl.$key.sha256($secret_key.session_id()).$serialized_data), 
 +      $secret_key); 
 +    // Serialize these data with special/simple format. 
 +    return __serialize__(['mac'=>$mac, 'ttl'=>$ttl, 'key'=>$key, 'id'=>sha256($secret_key.session_id()),  'data'=>$serialized_data]);
   } else {   } else {
-    $mac = sha256($secret_key.$ttl.$key.$serialized_data); +    $mac = hash_hmac( 
-    return serialize['mac'=>$mac, 'ttl'=>$ttl, 'key'=>$key, 'data'=>$serialized_data];+      'sha256', 
 +      $ttl.$key.$serialized_data), 
 +      $secret_key); 
 +    // Serialize these data with special/simple format. 
 +    return __serialize__(['mac'=>$mac, 'ttl'=>$ttl, 'key'=>$key, 'data'=>$serialized_data]);
   }   }
 } }
Line 59: Line 69:
  
  
-==== How secure_unserialize() works ====+==== How unserialize_mhac() works ====
  
 Pseudo code Pseudo code
 <code php> <code php>
-function secure_unserialize(string $data_to_be_unserialized, string $secret_key) : mixed {+function unserialize_mhac(string $data_to_be_unserialized, mixed $secret_key) : mixed {
   if (strlen($secret_key) < 32) {   if (strlen($secret_key) < 32) {
     trigger_error('Too short secret key');     trigger_error('Too short secret key');
Line 69: Line 79:
   }   }
      
-  // Unserialize header and serialized data safely+  // Unserialize special format
   $tmp = __unserialize__($data_to_be_unserialized);   $tmp = __unserialize__($data_to_be_unserialized);
-  if ($tmp['ttl'] < time() {+  if ($tmp['ttl'] && $tmp['ttl'] < time() {
     // Serialized data is expired     // Serialized data is expired
     return FALSE;     return FALSE;
   }   }
      
-  if (isset($tmp['id'])) { +  $keys = is_array($secret_key) ?: array[$secret_key]; 
-    // Old session ID may be used if session module stores old IDs in internal data. +  foreach ($keys in $k) {  
-    // https://wiki.php.net/rfc/precise_session_management +    if (isset($tmp['id'])) { 
-    $mac = sha256($secret_key.$tmp['ttl'].$tmp['key'].sha256($secret_key.session_id()).$tmp['data']); +      // Old session ID may be used if session module stores old IDs in internal data. 
-  } else { +      // https://wiki.php.net/rfc/precise_session_management 
-    $mac = sha256($secret_key.$tmp['ttl'].$tmp['key'].$tmp['data']); +      $mac = hash_hmac( 
-  +        'sha256', 
-   +        $tmp['ttl'].$tmp['key'].sha256($k.session_id()).$tmp['data']
-  if ($mac !== $tmp['mac']) { +        $k); 
-    return FALSE;+    } else { 
 +      $mac = hash_hmac( 
 +        'sha256', 
 +        $tmp['ttl'].$tmp['key'].$tmp['data']
 +        $k); 
 +    
 +    if ($mac !== $tmp['mac']) { 
 +       continue; 
 +    
 +    // Unserialize data normally and return 
 +    return unserialize($tmp['data']);
   }   }
-  // Unserialize data normally and return +  return FALSE;
-  return unserialize($tmp['data'])+
 } }
 </code> </code>
Line 139: Line 158:
 If session module stores old session ID, automatic fallback to old session ID may be supported. If session module stores old session ID, automatic fallback to old session ID may be supported.
  
-Compatibility functions for older releases may be implemented as PHP script.+Encryption is more secure than authentication codeImplement serialize_crypt/unserialize_crypt when standard encryption module is introduced. 
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
rfc/secure_serialization.1451504329.txt.gz · Last modified: 2017/09/22 13:28 (external edit)