Проверяет файл по одной или нескольким цифровым подписям Ed25519.
Проверяет файл по одной или нескольким цифровым подписям Ed25519.
Вычисляет SHA-384-хеш файла и проверяет подписи с помощью доверенных ключей WordPress, полученных через wp_trusted_keys(). Проверка считается успешной, если хотя бы одна подпись подходит хотя бы к одному ключу.
Подписи и доверенные ключи должны быть закодированы в Base64. Подписи и ключи неправильной длины пропускаются.
Функция проверяет подписи только по встроенным доверенным ключам WordPress. Передать собственный открытый ключ нельзя.
Для проверки необходимы алгоритм SHA-384 и нативное расширение Sodium либо достаточно быстрый полифил Sodium_Compat.
1 раз — 0.000417 сек (быстро) | 50000 раз — 1.72 сек (быстро) | PHP 8.2.28, WP 7.0.2
Хуков нет.
Возвращаетtrue|false|WP_Error.
true - подпись подтверждена.false - указан в официальном описании для случая, когда проверка не выполнялась, но актуальный код функции не возвращает это значение.verify_file_signature( $filename, $signatures, $filename_for_errors );
Ed25519 в формате Base64.Понятное название файла для сообщений об ошибках. Не влияет на путь к проверяемому файлу. При false используется имя файла из $filename.
По умолчанию: false
$result = verify_file_signature(
WP_CONTENT_DIR . '/upgrade/wordpress.zip',
$signature,
'wordpress.zip'
);
if ( is_wp_error( $result ) ) {
wp_die( esc_html( $result->get_error_message() ) );
}
function verify_file_signature( $filename, $signatures, $filename_for_errors = false ) {
if ( ! $filename_for_errors ) {
$filename_for_errors = wp_basename( $filename );
}
// Check we can process signatures.
if ( ! function_exists( 'sodium_crypto_sign_verify_detached' ) || ! in_array( 'sha384', array_map( 'strtolower', hash_algos() ), true ) ) {
return new WP_Error(
'signature_verification_unsupported',
sprintf(
/* translators: %s: The filename of the package. */
__( 'The authenticity of %s could not be verified as signature verification is unavailable on this system.' ),
'<span class="code">' . esc_html( $filename_for_errors ) . '</span>'
),
( ! function_exists( 'sodium_crypto_sign_verify_detached' ) ? 'sodium_crypto_sign_verify_detached' : 'sha384' )
);
}
// Verify runtime speed of Sodium_Compat is acceptable.
if ( ! extension_loaded( 'sodium' ) && ! ParagonIE_Sodium_Compat::polyfill_is_fast() ) {
$sodium_compat_is_fast = false;
// Allow for an old version of Sodium_Compat being loaded before the bundled WordPress one.
if ( method_exists( 'ParagonIE_Sodium_Compat', 'runtime_speed_test' ) ) {
/*
* Run `ParagonIE_Sodium_Compat::runtime_speed_test()` in optimized integer mode,
* as that's what WordPress utilizes during signing verifications.
*/
// phpcs:disable WordPress.NamingConventions.ValidVariableName
$old_fastMult = ParagonIE_Sodium_Compat::$fastMult;
ParagonIE_Sodium_Compat::$fastMult = true;
$sodium_compat_is_fast = ParagonIE_Sodium_Compat::runtime_speed_test( 100, 10 );
ParagonIE_Sodium_Compat::$fastMult = $old_fastMult;
// phpcs:enable
}
/*
* This cannot be performed in a reasonable amount of time.
* https://github.com/paragonie/sodium_compat#help-sodium_compat-is-slow-how-can-i-make-it-fast
*/
if ( ! $sodium_compat_is_fast ) {
return new WP_Error(
'signature_verification_unsupported',
sprintf(
/* translators: %s: The filename of the package. */
__( 'The authenticity of %s could not be verified as signature verification is unavailable on this system.' ),
'<span class="code">' . esc_html( $filename_for_errors ) . '</span>'
),
array(
'php' => PHP_VERSION,
'sodium' => defined( 'SODIUM_LIBRARY_VERSION' ) ? SODIUM_LIBRARY_VERSION : ( defined( 'ParagonIE_Sodium_Compat::VERSION_STRING' ) ? ParagonIE_Sodium_Compat::VERSION_STRING : false ),
'polyfill_is_fast' => false,
'max_execution_time' => ini_get( 'max_execution_time' ),
)
);
}
}
if ( ! $signatures ) {
return new WP_Error(
'signature_verification_no_signature',
sprintf(
/* translators: %s: The filename of the package. */
__( 'The authenticity of %s could not be verified as no signature was found.' ),
'<span class="code">' . esc_html( $filename_for_errors ) . '</span>'
),
array(
'filename' => $filename_for_errors,
)
);
}
$trusted_keys = wp_trusted_keys();
$file_hash = hash_file( 'sha384', $filename, true );
mbstring_binary_safe_encoding();
$skipped_key = 0;
$skipped_signature = 0;
foreach ( (array) $signatures as $signature ) {
$signature_raw = base64_decode( $signature );
// Ensure only valid-length signatures are considered.
if ( SODIUM_CRYPTO_SIGN_BYTES !== strlen( $signature_raw ) ) {
++$skipped_signature;
continue;
}
foreach ( (array) $trusted_keys as $key ) {
$key_raw = base64_decode( $key );
// Only pass valid public keys through.
if ( SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES !== strlen( $key_raw ) ) {
++$skipped_key;
continue;
}
if ( sodium_crypto_sign_verify_detached( $signature_raw, $file_hash, $key_raw ) ) {
reset_mbstring_encoding();
return true;
}
}
}
reset_mbstring_encoding();
return new WP_Error(
'signature_verification_failed',
sprintf(
/* translators: %s: The filename of the package. */
__( 'The authenticity of %s could not be verified.' ),
'<span class="code">' . esc_html( $filename_for_errors ) . '</span>'
),
// Error data helpful for debugging:
array(
'filename' => $filename_for_errors,
'keys' => $trusted_keys,
'signatures' => $signatures,
'hash' => bin2hex( $file_hash ),
'skipped_key' => $skipped_key,
'skipped_sig' => $skipped_signature,
'php' => PHP_VERSION,
'sodium' => defined( 'SODIUM_LIBRARY_VERSION' ) ? SODIUM_LIBRARY_VERSION : ( defined( 'ParagonIE_Sodium_Compat::VERSION_STRING' ) ? ParagonIE_Sodium_Compat::VERSION_STRING : false ),
)
);
}
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Функция WordPress: array_any() | 0 | 10 | 20-07-2026 |
| 2 | Функция WordPress: wp_fast_hash() | 0 | 18.33 | 20-07-2026 |
| 3 | Функция WordPress: array_all() | 0 | 8.26 | 20-07-2026 |
| 4 | Функция WordPress: wp_has_ability_category() | 0 | 10 | 20-07-2026 |
| 5 | Функция WordPress: get_language_attributes() | 0 | 32.22 | 27-07-2026 |
| 6 | Функция WordPress: array_find_key() | 0 | 10 | 20-07-2026 |
| 7 | Функция WordPress: wpdb::_escape() | 0 | 18.33 | 04-08-2026 |
| 8 | Функция WordPress: array_find() | 0 | 10 | 20-07-2026 |
| 9 | Функция WordPress: wp_register_core_ability_categories() | 0 | 7.66 | 20-07-2026 |
| 10 | Функция WordPress: wpdb::_real_escape() | 0 | 18.33 | 04-08-2026 |