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
Last revisionBoth sides next revision
rfc:secure_serialization [2015/12/30 03:26] – Add future scope - compat functions for older releases. yohgakirfc:secure_serialization [2017/09/22 13:28] – external edit 127.0.0.1
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=36000 [,bool $session_only=FALSE]]]) +  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>
  
-  * Add system wide secret key INI setting. 
  
-  serialize_secret - Secret string key used for authentication code +==== How serialize_mhac() works ====
-  serialize_ttl - Serialized data TTL +
- +
-==== How secure_serialize() works ====+
  
 Pseudo code Pseudo code
 <code php> <code php>
-function secure_serialize(string $data_to_be_serialized, string $secret_key = '', int $ttl = 36000, bool $session_only = FALSE) : string { +function secure_serialize(string $data_to_be_serialized, string $secret_key, int $ttl=1800, bool $session_only = TRUE) : string {
-  $secret_key = $secret_key ?: ini_get('serialize_secret');+
   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 (ini_get('serialize_ttl')) { +  if ($ttl < 0) { 
-    $ttl = time() + ini_get('serialize_ttl'); +    trigger_error('Invalid TTL'); 
-  } else { +    return FALSE;
-    $ttl = $ttl ?: time() + $ttl// 10 hours TTL by default+
   }   }
 +  $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 52: Line 47:
      
   $serialized_data = serialize($data_to_be_serialized);   $serialized_data = serialize($data_to_be_serialized);
-  if ($session_only{ +  $keys = is_array($secret_key?: array(secret_key); 
-    if (!session_id()) { +   
-      trigger_error('Session is not started'); +  if ($session_only && session_id()) {
-      return FALSE; +
-    }+
     // 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 68: Line 69:
  
  
-==== How secure_unserialize() works ====+==== How unserialize_mhac() works ====
  
 Pseudo code Pseudo code
 <code php> <code php>
-function secure_serialize(string $data_to_be_unserialized, string $secret_key = '') : mixed { +function unserialize_mhac(string $data_to_be_unserialized, mixed $secret_key) : mixed {
-  $secret_key = $secret_key ?: ini_get('serialize_secret');+
   if (strlen($secret_key) < 32) {   if (strlen($secret_key) < 32) {
     trigger_error('Too short secret key');     trigger_error('Too short secret key');
Line 79: Line 79:
   }   }
      
-  $tmp = unserialize($data_to_be_unserialized); +  // Unserialize special format 
-  if ($tmp['ttl'] < time() {+  $tmp = __unserialize__($data_to_be_unserialized); 
 +  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 store old IDs in internal data. +  foreach ($keys in $k) {  
-    $mac = sha256($secret_key.$tmp['ttl'].$tmp['key'].sha256($secret_key.session_id()).$tmp['data']); +    if (isset($tmp['id'])) { 
-  } else { +      // Old session ID may be used if session module stores old IDs in internal data. 
-    $mac = sha256($secret_key.$tmp['ttl'].$tmp['key'].$tmp['data']); +      // https://wiki.php.net/rfc/precise_session_management 
-  +      $mac = hash_hmac( 
-   +        'sha256', 
-  if ($mac !== $tmp['mac']) { +        $tmp['ttl'].$tmp['key'].sha256($k.session_id()).$tmp['data']
-    return FALSE;+        $k); 
 +    } 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']);
   }   }
-  return $tmp['data']+  return FALSE;
 } }
 </code> </code>
Line 132: Line 144:
   * php.ini-production values   * php.ini-production values
  
- +No changes.
-  * serialize_secret - Default '' for allSecret string used for authentication code +
-  * serialize_ttl - Default 36000 (10 hours) for all. Authentication code TTL+
  
 ===== Open Issues ===== ===== Open Issues =====
Line 148: 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.txt · Last modified: 2018/03/01 23:18 by carusogabriel