EN VI

In PHP openssl, how to get public certificate PEM for website?

2024-03-11 21:00:05
In PHP openssl, how to get public certificate PEM for website?

To get the public certificate (PEM) for a website in FireFox, I do this:

  1. Go to website, eg., https://stackoverflow.com , and click on padlock icon in address bar.
  2. Click on Connection secure -> More Information -> Security -> View Certificate
  3. In the new window that opens, download PEM (cert)

This gives:

-----BEGIN CERTIFICATE-----
MIIDmDCCAx6gAwIBAgISA4YbMJPyxWufWI8WdrDgUY+VMAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
MTAeFw0yNDAxMTQxODAwNTZaFw0yNDA0MTMxODAwNTVaMBwxGjAYBgNVBAMTEXN0
YWNrb3ZlcmZsb3cuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPgjIX08
tuE/uvVUobBWnJMDeL6BKjb8j7zz/RoCOvebPlGobHx8SDF4EJFSJgiHUXlDzQ5L
U5CuIq5aRcjjHqOCAigwggIkMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU5Mq9ZzT5
BBM9m7f/HapxalI+qHgwHwYDVR0jBBgwFoAUWvPtK/w2wjd5uVIw6lRvz1XLLqww
VQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vZTEuby5sZW5jci5v
cmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lMS5pLmxlbmNyLm9yZy8wMQYDVR0RBCow
KIITKi5zdGFja292ZXJmbG93LmNvbYIRc3RhY2tvdmVyZmxvdy5jb20wEwYDVR0g
BAwwCjAIBgZngQwBAgEwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgA7U3d1Pi25
gE6LMFsG/kA7Z9hPw/THvQANLXJv4frUFwAAAY0JWS8tAAAEAwBHMEUCIQDH271z
hdbRSKpKOrtRJljJ6BEkHcPgD+s0dLncf9yFEAIgPMOgq9/pEsJwGwtps4k/1U7D
4+0vGWFiQedcuCUgs0UAdgDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1
mwAAAY0JWS8nAAAEAwBHMEUCIAq5udOppKxQdINTQqkMR/weK5/1BgUuvsJ9AKxa
8jhyAiEAgajLB6GcESqIIV9GKYkSIACjZW/a8K7JuYVloj57zTQwCgYIKoZIzj0E
AwMDaAAwZQIwXYgUk4dYoDo7UPRFJjRfyAgGL3k+7rt+wN68vGdaIxKaxgW2gB1E
e9f9Ed4VFb4dAjEA3t3VGikIzLl1L5LkAFSQjrp5SZMpnr8h+5zLCnoK3tE98Ck0
HBHbXS573G/ixn2m
-----END CERTIFICATE-----

I am trying to do the same in PHP, but am ending up with a different certificate.

This is my code:

$url = "ssl://stackoverflow.com:443"; // Use ssl:// or tls:// rather than https://

$context = stream_context_create( ["ssl" => array(
    "capture_peer_cert" => true,
    //"capture_peer_cert_chain" => true,
    'protocol' => 'SSLv3'
)] );
$client = stream_socket_client( $url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context );
var_dump( $errno );
var_dump( $errstr );

$params = stream_context_get_params( $client );
//var_dump( $params );

$loc = $params["options"]["ssl"]["peer_certificate"];
$key = openssl_pkey_get_public( $loc );

$details = openssl_pkey_get_details( $key );
var_dump( $details["key"] );

But I end up with this certificate:

-----BEGIN PUBLIC KEY----- 
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPgjIX08tuE/uvVUobBWnJMDeL6B 
Kjb8j7zz/RoCOvebPlGobHx8SDF4EJFSJgiHUXlDzQ5LU5CuIq5aRcjjHg==
-----END PUBLIC KEY-----

I've tried various changes to the code, but nothing is giving me the required PEM files.

Can anyone see the change I need to make in order to end up with the same PEM data that is available via FireFox?

Solution:

The certificate obtained in the browser is in the PEM-encoded format.

You can obtain the public certificate in the PEM-encoded format in your program by applying the openssl-x509-export function.

$loc = $params["options"]["ssl"]["peer_certificate"];
// $key = openssl_pkey_get_public( $loc );

// $details = openssl_pkey_get_details( $key );
// var_dump( $details["key"] );
$out = '';

$key = openssl_x509_export($loc, $out);
var_dump($out);
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login