Encrypt & Decrypt Plugin Options

Sometimes, you want to collect information in your plugin settings page that you may not want to be easily readable from the database as plain text. For example, you might want to store a site owner’s API key for a service. There are a few considerations that must be met:

  1. The site-owner must be able to enter, update, and remove the API key if desired.
  2. If anyone looks in the database at the plugin option, or opens up the settings page, the key should not be human readable.
  3. The key must be recoverable, since we’ll need to use it to make API calls.

With these things in mind, here’s the approach we’ll take:

<?php
//Registers the pre_update_option filter for elements to encrypt. Format pre_update_option_(option name)
//Only do this for ones you want encrypted... in this case, first and third options.
function yourplugin_init() {
	add_filter( 'pre_update_option_your_first_option', 'yourplugin_update_option', 10, 2 );
	add_filter( 'pre_update_option_your_third_option', 'yourplugin_update_option', 10, 2 );
}
add_action( 'init', 'yourplugin_init' );

//Converts option value to encrypted form, only if it has changed
function yourplugin_update_option( $new_value, $old_value ) {
	if ($new_value != $old_value) {
		$cypher = 'aes-256-cbc'; //Pick the cypher to use
		$key = md5(SECURE_AUTH_SALT); //SECURE_AUTH_SALT can be replaced with any unique string.
    $new_value = openssl_encrypt("$new_value","$cypher","$key");
	}
	return $new_value;
}

//A function to retrieve the decrypted value of the options, to use them in your plugin
function yourplugin_decrypt_option($option) {
	 $cypher = 'aes-256-cbc'; //Be sure to use the same cypher as above
	 $key = md5(SECURE_AUTH_SALT); //Be sure to use same $key as above
	 $decrypted_value = openssl_decrypt("$option","$cypher","$key");
	 return $decrypted_value;
}