$defined The salts wp-config.php defines, by name. */ public static function salts_usable( array $defined ): bool { $counts = array_count_values( array_values( $defined ) ); foreach ( self::DERIVED as $name ) { $value = $defined[ $name ] ?? ''; if ( '' === $value || 'put your unique phrase here' === $value || $counts[ $value ] > 1 ) { return false; } } return true; } /** The key: from SHOWBITS_ENCRYPTION_KEY if defined, else from AUTH_KEY and SECURE_AUTH_KEY with their salts. */ private static function key(): string { $material = defined( 'SHOWBITS_ENCRYPTION_KEY' ) && is_string( SHOWBITS_ENCRYPTION_KEY ) && '' !== SHOWBITS_ENCRYPTION_KEY ? SHOWBITS_ENCRYPTION_KEY : wp_salt( 'auth' ) . wp_salt( 'secure_auth' ); return hash_hkdf( 'sha256', $material, SODIUM_CRYPTO_SECRETBOX_KEYBYTES, 'showbits-credentials' ); } /** Seals a secret: a version mark, then nonce and ciphertext in base64. */ public static function seal( string $plain ): string { $nonce = random_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ); return self::PREFIX . base64_encode( $nonce . sodium_crypto_secretbox( $plain, $nonce, self::key() ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode } /** Opens a sealed secret; null when it is not one or the key changed. */ public static function open( string $sealed ): ?string { if ( ! str_starts_with( $sealed, self::PREFIX ) ) { return null; } $raw = base64_decode( substr( $sealed, strlen( self::PREFIX ) ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode if ( false === $raw || strlen( $raw ) <= SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ) { return null; } $plain = sodium_crypto_secretbox_open( substr( $raw, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ), substr( $raw, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ), self::key() ); return false === $plain ? null : $plain; } }