'BackWPup_Encryption_OpenSSL', BackWPup_Encryption_Mcrypt::PREFIX => 'BackWPup_Encryption_Mcrypt', BackWPup_Encryption_Fallback::PREFIX => 'BackWPup_Encryption_Fallback', ); /** * * Encrypt a string using the best algorithm available. * * In case the given string is encrypted with a weaker algorithm, it will first be decrypted then the plain text * obtained is encrypted with the better algorithm available and returned. * * @param string $string value to encrypt * * @return string encrypted string */ public static function encrypt( $string ) { if ( ! is_string( $string ) || ! $string ) { return ''; } try { $cypher_class = self::cypher_class_for_string( $string ); } catch ( Exception $e ) { /** @TODO what to do here? The string is encrypted, but cypher used to encrypt isn't supported in current system */ return $string; } try { list( $key, $key_type ) = self::get_encrypt_info( $cypher_class, $string ); } catch ( Exception $e ) { /** @TODO what to do here? The string is encrypted, a custom key was used to encrypt, but it is not available anymore */ return $string; } $best_cipher_class = self::best_cypher(); // The given string is not encrypted, let's encrypt it and return if ( ! $cypher_class ) { /** @var BackWPup_Encryption_OpenSSL|BackWPup_Encryption_Mcrypt|BackWPup_Encryption_Fallback $best_cypher */ $best_cypher = new $best_cipher_class( $key, $key_type ); return $best_cypher->encrypt( $string ); } $encryption_count = substr_count( $string, self::PREFIX ); // The given string is encrypted once using best cypher, let's just return it if ( $encryption_count === 1 && $cypher_class === $best_cipher_class ) { return $string; } /** @var BackWPup_Encryption_OpenSSL|BackWPup_Encryption_Mcrypt|BackWPup_Encryption_Fallback $cypher */ $cypher = new $cypher_class( $key, $key_type ); $string = $cypher->decrypt( $string ); return self::encrypt( $string ); } /** * * Decrypt a string (Passwords) * * @param string $string value to decrypt * * @return string decrypted string */ public static function decrypt( $string ) { if ( ! is_string( $string ) || ! $string ) { return ''; } try { $cypher_class = self::cypher_class_for_string( $string ); } catch ( Exception $e ) { /** @TODO what to do here? The cypher used to encrypt is not supported in current system */ return ''; } if ( ! $cypher_class ) { /** @TODO what to do here? The string seems not encrypted or maybe is corrupted */ return $string; } try { list( $key, $key_type ) = self::get_encrypt_info( $cypher_class, $string ); } catch ( Exception $e ) { /** @TODO what to do here? A custom key was used to encrypt but it is not available anymore */ return ''; } /** @var BackWPup_Encryption_OpenSSL|BackWPup_Encryption_Mcrypt|BackWPup_Encryption_Fallback $cypher */ $cypher = new $cypher_class( $key, $key_type ); return trim( stripslashes( $cypher->decrypt( $string ) ), "\0" ); } /** * @param string $string * * @return string * @throws Exception */ private static function cypher_class_for_string( $string ) { foreach ( self::$classes as $prefix => $class ) { $enc_prefix = self::PREFIX . $prefix; if ( strpos( $string, $enc_prefix ) !== 0 ) { continue; } if ( ! call_user_func( array( $class, 'supported' ) ) ) { throw new Exception( "Give string was encrypted using {$class} but it is not currently supported in this system." ); } return $class; } return ''; } /** * @return string */ private static function best_cypher() { foreach ( self::$classes as $prefix => $class ) { if ( ! call_user_func( array( $class, 'supported' ) ) ) { continue; } return $class; } // This should never happen because BackWPup_Encryption_Fallback::supported() always returns true return ''; } /** * @param string|null $class * @param string $string * * @return array * @throws Exception */ private static function get_encrypt_info( $class = null, $string = '' ) { $default_key = DB_NAME . DB_USER . DB_PASSWORD; if ( ! is_string( $class ) || ! $class ) { return defined( 'BACKWPUP_ENC_KEY' ) ? array( BACKWPUP_ENC_KEY, self::KEY_TYPE_CUSTOM ) : array( $default_key, '' ); } $enc_prefix = self::PREFIX . constant( "{$class}::PREFIX" ); $has_custom_key = strpos( $string, $enc_prefix . self::KEY_TYPE_CUSTOM ) === 0; if ( $has_custom_key && ! defined( 'BACKWPUP_ENC_KEY' ) ) { throw new Exception( "Give string was encrypted using a custom key but 'BACKWPUP_ENC_KEY' constant is not defined anymore." ); } if ( $has_custom_key ) { return array( BACKWPUP_ENC_KEY, self::KEY_TYPE_CUSTOM ); } return array( $default_key, '' ); } }