Aller au contenu
ecdsa.com
PHP OpenSSL extensionPHP

Message d’erreur

openssl_verify(): Supplied key param cannot be coerced into a public key

Également affiché sous la forme

  • openssl_sign(): Supplied key param cannot be coerced into a private key
  • Warning: openssl_verify(): Supplied key param cannot be coerced into a public key

Le nom de la fonction varie (`openssl_verify`, `openssl_sign`, `openssl_seal`, `openssl_public_encrypt`…), de même que le type de clé (« public key » / « private key »). Avec `display_errors` activé, PHP ajoute le préfixe « Warning: ».

PHP OpenSSL extension — warning from openssl_verify / openssl_sign / openssl_seal

Ce que cela signifie

Les fonctions OpenSSL de PHP acceptent une clé sous forme de texte PEM, de chemin `file://` ou d’objet clé, et la valeur que vous avez passée n’a pas pu être convertie en clé du type requis (publique pour vérifier, privée pour signer). C’est un avertissement, pas une exception : la fonction renvoie `false` (ou `-1`), et le code qui teste uniquement `=== 1` le traite silencieusement comme une « signature invalide ». La raison sous-jacente fournie par OpenSSL est disponible via `openssl_error_string()`.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Charger la clé explicitement et faire apparaître la raison donnée par OpenSSL

    `openssl_pkey_get_public` / `_private` renvoient `false` en cas d’échec ; appelez `openssl_error_string()` jusqu’à épuisement des messages pour journaliser la cause, et arrêtez-vous au lieu de poursuivre avec une vérification qui a échoué.

    php
    $pem = str_replace('\\n', "\n", getenv('JWT_PUBLIC_KEY'));   // undo escaped newlines
    $publicKey = openssl_pkey_get_public($pem);
    if ($publicKey === false) {
        while ($msg = openssl_error_string()) {
            error_log($msg);                                     // the real OpenSSL reason
        }
        throw new RuntimeException('JWT_PUBLIC_KEY is not a usable public key');
    }
    $ok = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256) === 1;
  2. 2.

    Utiliser file:// pour les chemins de fichier et transmettre les phrases de passe

    Rendez explicite la source de la clé : soit le contenu PEM, soit un URI `file://`, plus la phrase de passe pour les clés chiffrées.

    php
    // Paths need the file:// scheme; encrypted keys need their passphrase.
    $privateKey = openssl_pkey_get_private('file:///etc/app/private.pem', getenv('KEY_PASSPHRASE') ?: null);

Erreurs associées

Parcourir toute la base de données des erreurs de signature