简体   繁体   中英

Curl failed with error #58: unable to use client certificate (no key found or wrong pass phrase?)

I get this error : Fatal error: Curl failed with error #58: unable to use client certificate (no key found or wrong pass phrase?)

I have a script that extracts the certificate information from a .p12 file. I thought this was the problem to start, however I used this to paste the contents of my generated .pem file : https://www.sslshopper.com/certificate-decoder.html and it decodes/sees it all fine. So I assume the .pem is ok.

$ch = curl_init();
            curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
                  curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSLCERT, 'cert.pem'); 
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            // converting
            $response = curl_exec($ch); 
            // converting
            $response1 = str_replace("<soap:Body>","",$response);
            $response2 = str_replace("</soap:Body>","",$response1);
            if($response === false){
              throw new Exception(curl_error($ch), curl_errno($ch));
            }

The pem file is as such :

-----BEGIN CERTIFICATE-----
<cert bla bla>
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
<key bla bla>
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
<cert bla bla>
-----END CERTIFICATE-----–

Any suggestions welcomed.

Thanks

Firstly a couple of comments:

  • By using these settings, you're opening yourself to potential MITM attacks :

     curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 

    You'd normally want VERIFYHOST=2 and VERIFYPEER=true (which should be the default anyway). Doing the verification correctly also implies you're going to need to set up a CA cert or the server cert in CAINFO or CAPATH. I'll quote the PHP/curl documentation for this option here:

    Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.

  • Pasting your private key (which you get in the -----BEGIN PRIVATE KEY----- block) into a remote website you don't know much about isn't necessarily a good idea. Your private key is meant to remain private. You can use openssl x509 and openssl rsa to check the formats are as you expect.

There are two options in libcurl : CURLOPT_SSLCERT and CURLOPT_SSLKEY , for the certificate and its private key, respectively. I must admit I haven't tried the PHP cURL bindings recently, and some tools will indeed let you put both cert and private key in the same file (like you've done), but while some comments in the PHP documentation suggest you can do this, this isn't really mentioned in libcurl 's documentation (you're not using the P12 format here). In addition, libcurl itself doesn't document CURLOPT_SSLCERTPASSWD (which would make sense for a password-protected key in the cert file), so there might be some slight difference in the PHP bindings and libcurl itself (you'll find most other options are almost a direct mapping).

I'd suggest moving what's between -----BEGIN/END PRIVATE KEY----- into a separate file and pointing CURLOPT_SSLKEY to that file path, and keeping the certificate (and presumably its chain, the following certs) with the current settings. Make sure the certificate chain is in the right order, in particular make sure that the first one is your client cert (for which you have the private key). You can check the content of each -----BEGIN/END CERTIFICATE----- block by pasting it into the standard input of openssl x509 -text -noout . Each of these blocks will give you a subject and issuer. A certificate with Subject X and Issuer Y should be followed by a certificate with Subject Y and Issuer Z (and so on).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM