*/ public static function get(string $provider): array { $stored = get_option(self::OPTION_KEY, []); $record = is_array($stored) ? ($stored[sanitize_key($provider)] ?? null) : null; if (!is_array($record)) { return []; } $plain = self::decrypt($record); if ($plain === '') { return []; } $data = json_decode($plain, true); if (!is_array($data)) { return []; } $clean = []; foreach ($data as $key => $value) { if (is_string($key) && is_string($value)) { $clean[sanitize_key($key)] = $value; } } return $clean; } /** @param array $changes */ public static function update(string $provider, array $changes): bool { $provider = sanitize_key($provider); if (!in_array($provider, ['aliyun', 'tencent'], true)) { return false; } $current = self::get($provider); foreach ($changes as $key => $value) { $key = sanitize_key((string) $key); if ($key === '') { continue; } if ($value === null) { unset($current[$key]); } elseif (is_string($value) && $value !== '') { $current[$key] = $value; } } $stored = get_option(self::OPTION_KEY, []); $stored = is_array($stored) ? $stored : []; if ($current === []) { unset($stored[$provider]); } else { $record = self::encrypt((string) wp_json_encode($current)); if (is_wp_error($record)) { return false; } $stored[$provider] = $record; } return update_option(self::OPTION_KEY, $stored, false) || get_option(self::OPTION_KEY, []) === $stored; } /** @return array */ public static function status(string $provider): array { $status = []; foreach (self::get($provider) as $key => $value) { $status[$key] = [ 'configured' => $value !== '', 'fingerprint' => $value !== '' ? substr(hash('sha256', $value), -4) : '', ]; } return $status; } /** @return array|\WP_Error */ private static function encrypt(string $plain) { $key = self::key(); if (function_exists('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) { $nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES); $cipher = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($plain, self::CONTEXT, $nonce, $key); return ['driver' => 'sodium', 'nonce' => base64_encode($nonce), 'cipher' => base64_encode($cipher)]; } if (function_exists('openssl_encrypt')) { $nonce = random_bytes(12); $tag = ''; $cipher = openssl_encrypt($plain, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag, self::CONTEXT); if (!is_string($cipher)) { return new \WP_Error('aksrt_identity_encrypt', __('身份认证凭证加密失败', 'aksrt')); } return ['driver' => 'openssl', 'nonce' => base64_encode($nonce), 'tag' => base64_encode($tag), 'cipher' => base64_encode($cipher)]; } return new \WP_Error('aksrt_identity_crypto', __('服务器不支持安全凭证加密', 'aksrt')); } /** @param array $record */ private static function decrypt(array $record): string { $nonce = base64_decode((string) ($record['nonce'] ?? ''), true); $cipher = base64_decode((string) ($record['cipher'] ?? ''), true); if (!is_string($nonce) || !is_string($cipher)) { return ''; } $key = self::key(); if (($record['driver'] ?? '') === 'sodium' && function_exists('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) { $plain = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($cipher, self::CONTEXT, $nonce, $key); return is_string($plain) ? $plain : ''; } if (($record['driver'] ?? '') === 'openssl' && function_exists('openssl_decrypt')) { $tag = base64_decode((string) ($record['tag'] ?? ''), true); if (!is_string($tag)) { return ''; } $plain = openssl_decrypt($cipher, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag, self::CONTEXT); return is_string($plain) ? $plain : ''; } return ''; } private static function key(): string { return hash_hmac('sha256', self::CONTEXT, wp_salt('auth') . wp_salt('secure_auth'), true); } }