Title: WP_Recovery_Mode_Key_Service
Published: May 7, 2019
Last modified: August 20, 2026

---

# class WP_Recovery_Mode_Key_Service {}

## In this article

 * [Methods](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#methods)
 * [Source](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#source)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#wp--skip-link--target)

Core class used to generate and validate keys used to enter Recovery Mode.

## 󠀁[Methods](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#methods)󠁿

| Name | Description | 
| [WP_Recovery_Mode_Key_Service::clean_expired_keys](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/clean_expired_keys/) | Removes expired recovery mode keys. | 
| [WP_Recovery_Mode_Key_Service::generate_and_store_recovery_mode_key](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/generate_and_store_recovery_mode_key/) | Creates a recovery mode key. | 
| [WP_Recovery_Mode_Key_Service::generate_recovery_mode_token](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/generate_recovery_mode_token/) | Creates a recovery mode token. | 
| [WP_Recovery_Mode_Key_Service::get_keys](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/get_keys/) | Gets the recovery key records. | 
| [WP_Recovery_Mode_Key_Service::remove_key](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/remove_key/) | Removes a used recovery key. | 
| [WP_Recovery_Mode_Key_Service::update_keys](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/update_keys/) | Updates the recovery key records. | 
| [WP_Recovery_Mode_Key_Service::validate_recovery_mode_key](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/validate_recovery_mode_key/) | Verifies if the recovery mode key is correct. |

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#source)󠁿

    ```php
    #[AllowDynamicProperties]
    final class WP_Recovery_Mode_Key_Service {

    	/**
    	 * The option name used to store the keys.
    	 *
    	 * @since 5.2.0
    	 * @var string
    	 */
    	private $option_name = 'recovery_keys';

    	/**
    	 * Creates a recovery mode token.
    	 *
    	 * @since 5.2.0
    	 *
    	 * @return string A random string to identify its associated key in storage.
    	 */
    	public function generate_recovery_mode_token() {
    		return wp_generate_password( 22, false );
    	}

    	/**
    	 * Creates a recovery mode key.
    	 *
    	 * @since 5.2.0
    	 * @since 6.8.0 The stored key is now hashed using wp_fast_hash() instead of phpass.
    	 *
    	 * @param string $token A token generated by WP_Recovery_Mode_Key_Service::generate_recovery_mode_token().
    	 * @return string Recovery mode key.
    	 */
    	public function generate_and_store_recovery_mode_key( $token ) {
    		$key = wp_generate_password( 22, false );

    		$records = $this->get_keys();

    		$records[ $token ] = array(
    			'hashed_key' => wp_fast_hash( $key ),
    			'created_at' => time(),
    		);

    		$this->update_keys( $records );

    		/**
    		 * Fires when a recovery mode key is generated.
    		 *
    		 * @since 5.2.0
    		 *
    		 * @param string $token The recovery data token.
    		 * @param string $key   The recovery mode key.
    		 */
    		do_action( 'generate_recovery_mode_key', $token, $key );

    		return $key;
    	}

    	/**
    	 * Verifies if the recovery mode key is correct.
    	 *
    	 * Recovery mode keys can only be used once; the key will be consumed in the process.
    	 *
    	 * @since 5.2.0
    	 *
    	 * @param string $token The token used when generating the given key.
    	 * @param string $key   The plain text key.
    	 * @param int    $ttl   Time in seconds for the key to be valid for.
    	 * @return true|WP_Error True on success, error object on failure.
    	 */
    	public function validate_recovery_mode_key( $token, $key, $ttl ) {
    		$records = $this->get_keys();

    		if ( ! isset( $records[ $token ] ) ) {
    			return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) );
    		}

    		$record = $records[ $token ];

    		$this->remove_key( $token );

    		if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) {
    			return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) );
    		}

    		if ( ! wp_verify_fast_hash( $key, $record['hashed_key'] ) ) {
    			return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) );
    		}

    		if ( time() > $record['created_at'] + $ttl ) {
    			return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) );
    		}

    		return true;
    	}

    	/**
    	 * Removes expired recovery mode keys.
    	 *
    	 * @since 5.2.0
    	 *
    	 * @param int $ttl Time in seconds for the keys to be valid for.
    	 */
    	public function clean_expired_keys( $ttl ) {

    		$records = $this->get_keys();

    		foreach ( $records as $key => $record ) {
    			if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) {
    				unset( $records[ $key ] );
    			}
    		}

    		$this->update_keys( $records );
    	}

    	/**
    	 * Removes a used recovery key.
    	 *
    	 * @since 5.2.0
    	 *
    	 * @param string $token The token used when generating a recovery mode key.
    	 */
    	private function remove_key( $token ) {

    		$records = $this->get_keys();

    		if ( ! isset( $records[ $token ] ) ) {
    			return;
    		}

    		unset( $records[ $token ] );

    		$this->update_keys( $records );
    	}

    	/**
    	 * Gets the recovery key records.
    	 *
    	 * @since 5.2.0
    	 * @since 6.8.0 Each key is now hashed using wp_fast_hash() instead of phpass.
    	 *              Existing keys may still be hashed using phpass.
    	 *
    	 * @return array {
    	 *     Associative array of token => data pairs, where the data is an associative
    	 *     array of information about the key.
    	 *
    	 *     @type array ...$0 {
    	 *         Information about the key.
    	 *
    	 *         @type string $hashed_key The hashed value of the key.
    	 *         @type int    $created_at The timestamp when the key was created.
    	 *     }
    	 * }
    	 */
    	private function get_keys() {
    		return (array) get_option( $this->option_name, array() );
    	}

    	/**
    	 * Updates the recovery key records.
    	 *
    	 * @since 5.2.0
    	 * @since 6.8.0 Each key should now be hashed using wp_fast_hash() instead of phpass.
    	 *
    	 * @param array $keys {
    	 *     Associative array of token => data pairs, where the data is an associative
    	 *     array of information about the key.
    	 *
    	 *     @type array ...$0 {
    	 *         Information about the key.
    	 *
    	 *         @type string $hashed_key The hashed value of the key.
    	 *         @type int    $created_at The timestamp when the key was created.
    	 *     }
    	 * }
    	 * @return bool True on success, false on failure.
    	 */
    	private function update_keys( array $keys ) {
    		return update_option( $this->option_name, $keys, false );
    	}
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/class-wp-recovery-mode-key-service.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-includes/class-wp-recovery-mode-key-service.php#L14)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-includes/class-wp-recovery-mode-key-service.php#L14-L193)

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_recovery_mode_key_service/?output_format=md#changelog)󠁿

| Version | Description | 
| [5.2.0](https://developer.wordpress.org/reference/since/5.2.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_recovery_mode_key_service%2F)
before being able to contribute a note or feedback.