Laravel项目调用外部API时出现openssl_seal(): not a public key错误的排查求助
openssl_seal(): not a public key in Laravel Let’s dig into this error—it’s almost always related to how your public key is formatted or processed, not the server stack (XAMPP/Wampserver) itself. Here are the key checks you should run first:
1. Verify Your Public Key Format is Correct
openssl_seal requires a PEM-formatted RSA public key (with the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers/footers). If your API_KEY in .env is a base64-encoded version of the key, make sure:
- The original key (before base64 encoding) includes those required headers and footers.
- When you decode it with
base64_decode($public_key), the result is a valid PEM string, not raw binary data missing the markers.
For example, if your raw public key looks like this:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... ... -----END PUBLIC KEY-----
You should remove all line breaks, then base64-encode the entire string (including headers/footers) to store in API_KEY.
2. Validate the Public Key Before Using It
Add a quick validation step in your encrypt method to get a detailed error message from OpenSSL—this will tell you exactly why the key is being rejected:
public static function encrypt(array $data, string $public_key): array { // Clean up any stray whitespace/newlines from the env value $cleanKey = trim(str_replace(["\r", "\n"], '', $public_key)); $decodedKey = base64_decode($cleanKey); // Test if OpenSSL can parse the key $pubKeyResource = openssl_pkey_get_public($decodedKey); if (!$pubKeyResource) { throw new \RuntimeException( 'Invalid public key: ' . openssl_error_string() ); } // Now use the valid resource with openssl_seal openssl_seal(json_encode($data), $encrypted, $e_keys, [$pubKeyResource]); // Free the key resource to avoid memory leaks openssl_free_key($pubKeyResource); return [ 'hash' => base64_encode($encrypted), 'key' => base64_encode($e_keys[0]) ]; }
Running this will give you a specific error (e.g., "unable to load Public Key" due to missing headers) instead of the generic "not a public key" message.
3. Check for Base64 Decoding Issues
Sometimes values pulled from .env can have invisible whitespace or line breaks added accidentally. Using trim(str_replace(["\r", "\n"], '', $public_key)) before decoding ensures you’re working with a clean base64 string.
4. Rule Out Windows PHP OpenSSL Quirks
While switching from XAMPP to Wampserver didn’t fix it, Windows builds of PHP sometimes have OpenSSL configuration oddities:
- Ensure your Wampserver uses a recent, stable PHP version (8.1+ recommended)—older versions had bugs with OpenSSL key parsing on Windows.
- Check your
php.inifile to confirmopenssl.cafileandopenssl.capathare set correctly (pointing to valid CA certificates, though this is more for SSL requests than key parsing).
Quick Test to Isolate the Issue
Create a tiny standalone script to test just the key parsing:
<?php $publicKey = env('API_KEY'); $cleanKey = trim(str_replace(["\r", "\n"], '', $publicKey)); $decodedKey = base64_decode($cleanKey); $pubKey = openssl_pkey_get_public($decodedKey); if ($pubKey) { echo "Public key is valid!"; openssl_free_key($pubKey); } else { echo "Invalid key: " . openssl_error_string(); }
Run this with php scriptname.php—if it fails here, the problem is definitely with the key itself, not your Laravel code.
内容的提问来源于stack exchange,提问作者Josh

