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.