0

I found some instructions on encrypting an options field for a plugin here, using:

encrypt($input_string, $key){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$h_key = hash('sha256', $key, TRUE);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $h_key, $input_string, MCRYPT_MODE_ECB, $iv));

And here, recommending WP's Portable PHP Password hashing framework:

require_once( '/path/to/wp-includes/class-phpass.php' );
$wp_hasher = new PasswordHash( 8, TRUE );
$password = 'swordfish';
$hashed_password = $wp_hasher->HashPassword( $password );

But I'm having trouble because I want to display the decrypted password (if set) in the form field, but am not sure how to then encrypt it before sending to the DB.

The current code is as follows:

// Register and define the settings
add_action('admin_init', 'my_plugin_admin_init');

function my_plugin_admin_init(){
    register_setting(
        'my_plugin_options',
        'my_plugin_options',
        'my_plugin_validate_options'
    );

    add_settings_section(
        'my_plugin_main',
        'The Credentials',
        'my_plugin_section_text',
        'my_plugin'
    );

// Display and fill the form field
function my_plugin_password() {
    $options = get_option( 'my_plugin_options',__('Option Not Set') );
    if (isset($options['my_plugin_password'])) {
        $my_plugin_password = decrypt($options, $options['my_plugin_password'], SECURE_AUTH_SALT);
        $my_plugin_password_enc = encrypt($my_plugin_password, SECURE_AUTH_SALT);
    } else {
        $my_plugin_password = _e('YOUR PASSWORD');
        $my_plugin_password_enc = '';
    }
    // echo the field
    echo "<input id='my_plugin_password' name='my_plugin_options[my_plugin_password]' type='text' value='$my_plugin_password_enc' />";
}


add_settings_field(
            'my_password',
            'Enter Password: ',
            'my_password',
            'my_plugin',
            'my_plugin_main'
        ); 

And I think what's happening now is that an unencrypted password is being decrypted into something like this: @H!��f46vQa��,�v��3�1��(Ȥ��

The "encrypted" one just ends up looking like the input string followed by a string of As.

Do I need to add an update_option call somewhere, maybe?

Also wondering if it's more secure to do the encrypting and decrypting with JavaScript so only encrypted strings leave the client. But I'm not sure how that would work when a user logged in from another client.

2 Answers 2

1

There is no safe way to encrypt a password which is also reversible. The whole point of a hash function, such as is used for passwords, is that it is one-way.

You can encrypt it, not decrypt it.

If the password is decryptable, then you might as well not have the encryption in the first place. The point of encrypting passwords in the database is so that if somebody gets read-access to the database, they can't find out what your passwords are. All they see is hashed randomness. Since it's not reversible, then they can't decrypt it themselves.

You say that you need to store info in the database in an encrypted form, but you don't say why you need to do this. What is the specific type of threat or attack which you are protecting against, exactly? Every type of attack has countermeasures, you don't just encrypt because encryption magically makes things safer, you encrypt in specific ways to mitigate specific threats.

If you're communicating with some service, perhaps, then you might be better off using OAuth2 or similar to have the two services connect without the use of passwords.

Look for a better solution, at the high level. If you're encrypting passwords and then also need to decrypt them, you've probably gone way wrong in the initial concept in the first place.

3
  • No specific attack. It because the API developers asked us to store the user password that interacts with their API in an encrypted format. It looks like they offer some OAuth2 authorization, so maybe I'll look into that angle. auth.mindbodyonline.com/appintegration
    – MikeiLL
    Oct 10, 2014 at 17:24
  • Am I correct in understanding that Oauth2 implementation is relatively involved? If I do chose to pursue the slightly more secure method of encoding the plugin credentials prior to saving the option, can you point me in the right direction?
    – MikeiLL
    Oct 21, 2014 at 22:53
  • Wouldn't this help when the attacker has database access but not file access? Feb 15, 2016 at 20:46
1

You can intercept options being saved before they hit the database using an action and a filter.

https://codex.wordpress.org/Plugin_API/Filter_Reference/pre_update_option_(option_name)

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.