FRED™  3.0
FRED™: Framework for Rapid and Easy Development
Encrypt.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi\Fred;
4 
5 /**
6  * Encryption (and decryption) component.
7  */
8 class Encrypt extends Component{
9 
10  protected $_key = null; //!< Master key (used for padding).
11  protected $_keyFile = null; //!< File where master key is stored. If the file does not exist, a key is generated and saved.
12  protected $_method = 'AES-256-CTR'; //!< Encryption method (see openssl_get_cipher_methods()).
13  protected $_blockSize = 32000; //!< File encryption block size.
14 
15  /**
16  * Generate an encryption key.
17  * @param string $key Custom/user key.
18  * @return string Generated key based on custom/user key and master key (binary).
19  */
20  protected function key($key){
21  return sha1($key . $this->key,true) . $key . $this->key;
22  }
23  /**
24  * Generate an initialization vector.
25  * @param int $length Length of the initialization vector.
26  * @return string Generated initialization vector (binary).
27  */
28  protected function initVector(&$length = null){
29  $iv = openssl_random_pseudo_bytes($length = openssl_cipher_iv_length($this->_method),$strong);
30  if(!$strong) $this->component('log')->warning("Generated initialization vector for method '{$this->_method}' not cryptographically strong",__FILE__,__LINE__);
31  return $iv;
32  }
33  /**
34  * Encrypt a string.
35  * @param string $str Input string.
36  * @param string $key Key for encryption.
37  * @return string Encrypted data (binary). This includes the used method, so this can be safely changed.
38  */
39  public function str($str,$key = null){
40  $iv = $this->initVector();
41  return $this->_method . ':' . $iv . openssl_encrypt($str,$this->_method,$this->key($key),OPENSSL_RAW_DATA,$iv);
42  }
43  /**
44  * Decrypt an encrypted string.
45  * @param string $data String encrypted with str().
46  * @param string $key Key for decryption (same one as used with encryption).
47  * @return string Decrypted string.
48  */
49  public function decrypt($data,$key = null){
50  $length = openssl_cipher_iv_length($method = substr($data,0,$i = strpos($data,':')));
51  return openssl_decrypt(substr($data,$i + 1 + $length),$method,$this->key($key),OPENSSL_RAW_DATA,substr($data,$i + 1,$length));
52  }
53  /**
54  * Encrypt a file.
55  * @param string $source Original file.
56  * @param string $target File to write encrypted data to. This includes the used method and block size, so these can be
57  * safely changed.
58  * @param string $key Key for encryption.
59  * @return int Number of bytes written.
60  */
61  public function file($source,$target,$key = null){
62  $key = $this->key($key);
63  $source = fopen($source,'r');
64  $target = fopen($target,'w');
65  $config = $this->_method . ':' . $this->_blockSize;
66  $result = fwrite($target,pack('n',strlen($config)) . $config . ($iv = $this->initVector($length)));
67  while(!feof($source)){
68  $result += fwrite($target,$data = openssl_encrypt(fread($source,$this->_blockSize),$this->_method,$key,OPENSSL_RAW_DATA,$iv));
69  $iv = substr($data,0,$length);
70  }
71  fclose($source);
72  fclose($target);
73  return $result;
74  }
75  /**
76  * Decrypt an encrypted file.
77  * @param string $source File encrypted with file().
78  * @param string $target File to write decrypted data to.
79  * @param string $key Key for decryption (same one as used with encryption).
80  * @return int Number of bytes written.
81  */
82  public function decryptFile($source,$target,$key = null){
83  $key = $this->key($key);
84  $source = fopen($source,'r');
85  $target = fopen($target,'w');
86  list($method,$size) = explode(':',fread($source,unpack('n',fread($source,2))[1]));
87  $iv = fread($source,$length = openssl_cipher_iv_length($method));
88  $result = 0;
89  while(!feof($source)){
90  $result += fwrite($target,openssl_decrypt($data = fread($source,$size),$method,$key,OPENSSL_RAW_DATA,$iv));
91  $iv = substr($data,0,$length);
92  }
93  fclose($source);
94  fclose($target);
95  return $result;
96  }
97 
98  protected function getKey(){
99  if(!$this->_key && !($this->_key = $this->config('key'))){
100  if(!$this->_keyFile) throw new Exception('No master key (file)');
101  if(is_file($this->_keyFile)) $this->_key = file_get_contents($this->_keyFile);
102  else{
103  \Rsi\File::write($this->_keyFile,$this->_key = \Rsi\Str::random(256),0444);
104  $this->component('log')->warning('Generated an encryption master key',__FILE__,__LINE__,['key' => $this->_key]);
105  }
106  }
107  return $this->_key;
108  }
109 
110 }
config($key, $default=null)
Retrieve a config value.
Definition: Component.php:53
$_key
Master key (used for padding).
Definition: Encrypt.php:10
$_blockSize
File encryption block size.
Definition: Encrypt.php:13
$_method
Encryption method (see openssl_get_cipher_methods()).
Definition: Encrypt.php:12
key($key)
Generate an encryption key.
Definition: Encrypt.php:20
str($str, $key=null)
Encrypt a string.
Definition: Encrypt.php:39
Encryption (and decryption) component.
Definition: Encrypt.php:8
file($source, $target, $key=null)
Encrypt a file.
Definition: Encrypt.php:61
$_keyFile
File where master key is stored. If the file does not exist, a key is generated and saved...
Definition: Encrypt.php:11
decrypt($data, $key=null)
Decrypt an encrypted string.
Definition: Encrypt.php:49
decryptFile($source, $target, $key=null)
Decrypt an encrypted file.
Definition: Encrypt.php:82
Basic component class.
Definition: Component.php:8
initVector(&$length=null)
Generate an initialization vector.
Definition: Encrypt.php:28
component($name)
Get a component (local or default).
Definition: Component.php:80