delete_key_file( $file ); } /** * Encrypt data. * * @param mixed $value value. * @param int $site_id site_id. * @param bool $create_keys_file create_keys_file. * @return mixed */ public function encrypt_privkey( $value, $site_id = false, $create_keys_file = false ) { $data = $this->encrypt_data( $value ); if ( is_array( $data ) && ! empty( $data['en_data'] ) ) { if ( $create_keys_file && $site_id ) { static::encrypt_save_keys( $site_id, $data ); } return $data; } return array(); } /** * Decrypt data. * * @param mixed $encrypted encrypted. * @param int $site_id site id. * @return mixed */ public function decrypt_privkey( $encrypted, $site_id = false ) { $path = static::get_key_file( $site_id, true ); if ( ! file_exists( $path ) ) { return ''; } $values = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- private key files. $load_keys = explode( '-', $values ); if ( 3 <= count( $load_keys ) ) { return $this->decrypt_data( $encrypted, $load_keys ); } return ''; } /** * Encrypt save keys. * * @param int $site_id site id. * @param array $encrypted_data encrypted data. * @return mixed */ public static function encrypt_save_keys( $site_id, $encrypted_data ) { if ( is_array( $encrypted_data ) && ! empty( $encrypted_data['en_data'] ) ) { $priv_file = static::get_key_file( $site_id ); $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. return MainWP_Keys_Manager::instance()->save_key_file( $priv_file, $keys_encoded ); } return false; } /** * Encrypt data. * * @param mixed $data data. * @return mixed */ private function encrypt_data( $data ) { try { // Load or generate RSA keys. $privateKey = RSA::createKey( 2048 );// Generates a new 2048-bit RSA key pair. $publicKey = $privateKey->getPublicKey(); // Step 1: Generate a random AES key. $aes = new AES( 'cbc' ); // Use AES in CBC mode. $aesKey = Random::string( 32 ); // AES-256 key (32 bytes). $aesIV = Random::string( 16 ); // 16-byte IV for CBC mode. $aes->setKey( $aesKey ); $aes->setIV( $aesIV ); // Step 2: Encrypt the large data with AES. $encryptedData = $aes->encrypt( $data ); // Step 3: Encrypt the AES key and IV with RSA. $rsaEncryptedKey = $publicKey->encrypt( $aesKey ); $rsaEncryptedIV = $publicKey->encrypt( $aesIV ); $privateKeyString = $privateKey->toString( 'PKCS8' ); // Store in PKCS8 format for easy reuse. return array( 'en_data' => $encryptedData, 'priv_key' => $privateKeyString, 'en_key' => $rsaEncryptedKey, 'en_iv' => $rsaEncryptedIV, ); } catch ( \Exception $e ) { MainWP_Logger::instance()->debug( 'Encrypt Data :: [error=' . $e->getMessage() . ']' ); return false; } } /** * Decrypt data. * * @param mixed $encryptedData encrypted data. * @param array $load_keys load keys. * @return mixed */ public function decrypt_data( $encryptedData, $load_keys ) { try { //phpcs:disable WordPress.PHP.DiscouragedPHPFunctions -- base64_encode trust. $loadPrivateKeyString = base64_decode( $load_keys[0] ); $rsaEncryptedKey = base64_decode( $load_keys[1] ); $rsaEncryptedIV = base64_decode( $load_keys[2] ); //phpcs:enable // Load or generate RSA keys. $privateKey = RSA::loadPrivateKey( $loadPrivateKeyString ); $aes = new AES( 'cbc' ); // Use AES in CBC mode. // Decrypt the AES key and IV with RSA. $decryptedKey = $privateKey->decrypt( $rsaEncryptedKey ); $decryptedIV = $privateKey->decrypt( $rsaEncryptedIV ); // Decrypt the data with AES. $aes->setKey( $decryptedKey ); $aes->setIV( $decryptedIV ); return $aes->decrypt( $encryptedData ); } catch ( \Exception $e ) { MainWP_Logger::instance()->debug( 'Decrypt Data :: [error=' . $e->getMessage() . ']' ); return false; } } }