You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在保存到数据库前加密WordPress选项值

Fixing Your WordPress Option Encryption Code

Let's walk through the issues in your current code and get it working properly:

1. Incorrect Hook Usage & Parameter Mismatch

  • First off, you don't need to manually call apply_filters( 'pre_update_option_apikey', ... ) — WordPress automatically triggers this hook when the apikey option is being updated. You can delete that line entirely.
  • Your add_filter declares it passes 2 parameters, but your encryptData function only accepts 1. Worse, you're trying to use $old_value in the function without defining it, which will throw a PHP error. Fix the function signature to match the parameters the hook provides.

2. Broken RSA Key Generation Logic

Right now, you generate a brand new RSA key pair every time you update the apikey option. That's a critical problem: once you overwrite the public key in your pkey option, you'll never be able to decrypt any previously encrypted data. You should only generate the key pair once (like when your plugin/theme is activated), not on every update.

3. Reversed Encryption Direction

RSA encryption is typically used as:

  • Public key: Encrypts data (anyone can use this to encrypt, but only the private key can decrypt)
  • Private key: Decrypts data (keep this secure, never expose it publicly)

You're using openssl_private_encrypt right now, which uses the private key to encrypt — this is backwards for storing sensitive data in a database.


Corrected Code

First, add code to generate and store your RSA keys once on activation:

// Generate RSA keys once when the plugin is activated
register_activation_hook(__FILE__, 'generate_rsa_keypair');
function generate_rsa_keypair() {
    // Only generate if keys don't already exist
    if (!get_option('rsa_private_key')) {
        $config = [
            "digest_alg" => "sha512",
            "private_key_bits" => 4096,
            "private_key_type" => OPENSSL_KEYTYPE_RSA,
        ];

        $key_resource = openssl_pkey_new($config);
        openssl_pkey_export($key_resource, $private_key);
        
        $key_details = openssl_pkey_get_details($key_resource);
        $public_key = $key_details["key"];

        // Store keys securely (private key should never be exposed publicly)
        update_option('rsa_private_key', $private_key, '', 'yes');
        update_option('rsa_public_key', $public_key, '', 'yes');
    }
}

Then fix the encryption filter:

// Hook into the option update to encrypt the value
add_filter('pre_update_option_apikey', 'encrypt_apikey_before_save', 10, 2);

function encrypt_apikey_before_save($new_value, $old_value) {
    $public_key = get_option('rsa_public_key');
    
    // Fallback: return original value if public key isn't available
    if (!$public_key) {
        return $new_value;
    }

    $encrypted_data = '';
    // Use public key to encrypt the new value
    openssl_public_encrypt($new_value, $encrypted_data, $public_key);

    // Encode to base64 to avoid issues with binary data in the database
    return base64_encode($encrypted_data);
}

Bonus: Decryption Function

To retrieve and decrypt the stored value later, use this function:

function decrypt_stored_apikey() {
    $encrypted_value = get_option('apikey');
    $private_key = get_option('rsa_private_key');

    if (!$encrypted_value || !$private_key) {
        return false;
    }

    $decrypted_data = '';
    openssl_private_decrypt(base64_decode($encrypted_value), $decrypted_data, $private_key);
    
    return $decrypted_data;
}

内容的提问来源于stack exchange,提问作者Luca Pisoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:37:40