E_WARNING php auth_error ai_generated true

Warning: openssl_verify(): Supplied key param cannot be coerced into a public key in /var/www/app/src/Auth/JwtValidator.php on line 42

ID: php/openssl-key-format-mismatch

Also available as: JSON · Markdown · 中文
90%Fix Rate
88%Confidence
1Evidence
2023-09-05First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
PHP 7.4 active
PHP 8.0 active
PHP 8.1 active
PHP 8.2 active
PHP 8.3 active
OpenSSL 1.1.1 active
OpenSSL 3.0 active

Root Cause

The public key provided to openssl_verify() is in an unsupported format (e.g., PKCS#1 instead of PKCS#8, or missing proper PEM headers), causing OpenSSL to reject the key.

generic

中文

提供给openssl_verify()的公钥格式不受支持(例如PKCS#1而非PKCS#8,或缺少正确的PEM头),导致OpenSSL拒绝该密钥。

Official Documentation

https://www.php.net/manual/en/function.openssl-verify.php

Workarounds

  1. 95% success Ensure the public key is in PKCS#8 PEM format. Convert if needed using OpenSSL CLI: `openssl pkey -in private_key.pem -pubout -out public_key.pem`. Then load it in PHP with `$key = file_get_contents('/path/to/public_key.pem');` and ensure no extra whitespace.
    Ensure the public key is in PKCS#8 PEM format. Convert if needed using OpenSSL CLI: `openssl pkey -in private_key.pem -pubout -out public_key.pem`. Then load it in PHP with `$key = file_get_contents('/path/to/public_key.pem');` and ensure no extra whitespace.
  2. 90% success Use `openssl_get_publickey()` instead of passing the key string directly; this function auto-detects and converts formats. Example: `$pubKey = openssl_get_publickey(file_get_contents('key.pem')); if ($pubKey === false) { echo openssl_error_string(); }`
    Use `openssl_get_publickey()` instead of passing the key string directly; this function auto-detects and converts formats. Example: `$pubKey = openssl_get_publickey(file_get_contents('key.pem')); if ($pubKey === false) { echo openssl_error_string(); }`

中文步骤

  1. Ensure the public key is in PKCS#8 PEM format. Convert if needed using OpenSSL CLI: `openssl pkey -in private_key.pem -pubout -out public_key.pem`. Then load it in PHP with `$key = file_get_contents('/path/to/public_key.pem');` and ensure no extra whitespace.
  2. Use `openssl_get_publickey()` instead of passing the key string directly; this function auto-detects and converts formats. Example: `$pubKey = openssl_get_publickey(file_get_contents('key.pem')); if ($pubKey === false) { echo openssl_error_string(); }`

Dead Ends

Common approaches that don't work:

  1. 90% fail

    The issue is the key format structure (PEM headers, line breaks), not just encoding. A raw binary key without proper boundaries will fail the same way.

  2. 85% fail

    Extra whitespace or BOM can corrupt the PEM header; OpenSSL requires exact format: `-----BEGIN PUBLIC KEY-----` on its own line.