PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.3
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-encrypt-data-lib.php

class-mainwp-encrypt-data-lib.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.3, at class/class-mainwp-encrypt-data-lib.php

225 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 *
4 * Encrypts & Decrypts API Keys.
5 *
6 * @package MainWP/Dashboard
7 */
8
9 namespace MainWP\Dashboard;
10
11 use phpseclib3\Crypt\RSA;
12 use phpseclib3\Crypt\AES;
13 use phpseclib3\Crypt\Random;
14
15
16 // Exit if accessed directly.
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit;
19 }
20
21 /**
22 * Class MainWP_Encrypt_Data_Lib
23 *
24 * @package MainWP/Dashboard
25 */
26 class MainWP_Encrypt_Data_Lib { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
27
28 /**
29 * Private static variable to hold the single instance of the class.
30 *
31 * @static
32 *
33 * @var mixed Default null
34 */
35 private static $instance = null;
36
37 /**
38 * Method instance()
39 *
40 * Create a public static instance.
41 *
42 * @static
43 * @return static class.
44 */
45 public static function instance() {
46 if ( null === static::$instance ) {
47 static::$instance = new self();
48 }
49 MainWP_Keys_Manager::auto_load_files();
50 return static::$instance;
51 }
52
53 /**
54 * Method get_class_name()
55 *
56 * Get Class Name.
57 *
58 * @return string Class name.
59 */
60 public static function get_class_name() {
61 return __CLASS__;
62 }
63
64
65 /**
66 * Get key filename.
67 *
68 * @param int $site_id site id.
69 * @param bool $fullpath full path.
70 *
71 * @return string
72 */
73 public static function get_key_file( $site_id, $fullpath = false ) {
74 $file = 'mainwp_priv_encrypt_keys_' . $site_id;
75 if ( $fullpath ) {
76 MainWP_Keys_Manager::init_keys_dir();
77 $key_dir = MainWP_Keys_Manager::get_keys_dir();
78 return $key_dir . $file;
79 }
80 return $file;
81 }
82
83
84 /**
85 * Remove key file.
86 *
87 * @param int $site_id site id.
88 *
89 * @return void
90 */
91 public static function remove_key_file( $site_id ) {
92 $file = static::get_key_file( $site_id );
93 MainWP_Keys_Manager::instance()->delete_key_file( $file );
94 }
95
96 /**
97 * Encrypt data.
98 *
99 * @param mixed $value value.
100 * @param int $site_id site_id.
101 * @param bool $create_keys_file create_keys_file.
102 * @return mixed
103 */
104 public function encrypt_privkey( $value, $site_id = false, $create_keys_file = false ) {
105 $data = $this->encrypt_data( $value );
106 if ( is_array( $data ) && ! empty( $data['en_data'] ) ) {
107 if ( $create_keys_file && $site_id ) {
108 static::encrypt_save_keys( $site_id, $data );
109 }
110 return $data;
111 }
112 return array();
113 }
114
115 /**
116 * Decrypt data.
117 *
118 * @param mixed $encrypted encrypted.
119 * @param int $site_id site id.
120 * @return mixed
121 */
122 public function decrypt_privkey( $encrypted, $site_id = false ) {
123 $path = static::get_key_file( $site_id, true );
124 if ( ! file_exists( $path ) ) {
125 return '';
126 }
127 $values = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- private key files.
128 $load_keys = explode( '-', $values );
129 if ( 3 <= count( $load_keys ) ) {
130 return $this->decrypt_data( $encrypted, $load_keys );
131 }
132 return '';
133 }
134
135 /**
136 * Encrypt save keys.
137 *
138 * @param int $site_id site id.
139 * @param array $encrypted_data encrypted data.
140 * @return mixed
141 */
142 public static function encrypt_save_keys( $site_id, $encrypted_data ) {
143 if ( is_array( $encrypted_data ) && ! empty( $encrypted_data['en_data'] ) ) {
144 $priv_file = static::get_key_file( $site_id );
145 $keys_encoded = base64_encode( $encrypted_data['priv_key'] ) . '-' . base64_encode( $encrypted_data['en_key'] ) . '-' . base64_encode( $encrypted_data['en_iv'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode trust.
146 return MainWP_Keys_Manager::instance()->save_key_file( $priv_file, $keys_encoded );
147 }
148 return false;
149 }
150
151 /**
152 * Encrypt data.
153 *
154 * @param mixed $data data.
155 * @return mixed
156 */
157 private function encrypt_data( $data ) {
158 try {
159 // Load or generate RSA keys.
160 $privateKey = RSA::createKey( 2048 );// Generates a new 2048-bit RSA key pair.
161 $publicKey = $privateKey->getPublicKey();
162
163 // Step 1: Generate a random AES key.
164 $aes = new AES( 'cbc' ); // Use AES in CBC mode.
165 $aesKey = Random::string( 32 ); // AES-256 key (32 bytes).
166 $aesIV = Random::string( 16 ); // 16-byte IV for CBC mode.
167 $aes->setKey( $aesKey );
168 $aes->setIV( $aesIV );
169
170 // Step 2: Encrypt the large data with AES.
171 $encryptedData = $aes->encrypt( $data );
172 // Step 3: Encrypt the AES key and IV with RSA.
173 $rsaEncryptedKey = $publicKey->encrypt( $aesKey );
174 $rsaEncryptedIV = $publicKey->encrypt( $aesIV );
175
176 $privateKeyString = $privateKey->toString( 'PKCS8' ); // Store in PKCS8 format for easy reuse.
177
178 return array(
179 'en_data' => $encryptedData,
180 'priv_key' => $privateKeyString,
181 'en_key' => $rsaEncryptedKey,
182 'en_iv' => $rsaEncryptedIV,
183 );
184
185 } catch ( \Exception $e ) {
186 MainWP_Logger::instance()->debug( 'Encrypt Data :: [error=' . $e->getMessage() . ']' );
187 return false;
188 }
189 }
190
191
192 /**
193 * Decrypt data.
194 *
195 * @param mixed $encryptedData encrypted data.
196 * @param array $load_keys load keys.
197 * @return mixed
198 */
199 public function decrypt_data( $encryptedData, $load_keys ) {
200 try {
201 //phpcs:disable WordPress.PHP.DiscouragedPHPFunctions -- base64_encode trust.
202 $loadPrivateKeyString = base64_decode( $load_keys[0] );
203 $rsaEncryptedKey = base64_decode( $load_keys[1] );
204 $rsaEncryptedIV = base64_decode( $load_keys[2] );
205 //phpcs:enable
206
207 // Load or generate RSA keys.
208 $privateKey = RSA::loadPrivateKey( $loadPrivateKeyString );
209 $aes = new AES( 'cbc' ); // Use AES in CBC mode.
210 // Decrypt the AES key and IV with RSA.
211 $decryptedKey = $privateKey->decrypt( $rsaEncryptedKey );
212 $decryptedIV = $privateKey->decrypt( $rsaEncryptedIV );
213
214 // Decrypt the data with AES.
215 $aes->setKey( $decryptedKey );
216 $aes->setIV( $decryptedIV );
217
218 return $aes->decrypt( $encryptedData );
219 } catch ( \Exception $e ) {
220 MainWP_Logger::instance()->debug( 'Decrypt Data :: [error=' . $e->getMessage() . ']' );
221 return false;
222 }
223 }
224 }
225