Skip to content

Instantly share code, notes, and snippets.

@rdlowrey
Last active December 23, 2015 09:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdlowrey/6618710 to your computer and use it in GitHub Desktop.
Save rdlowrey/6618710 to your computer and use it in GitHub Desktop.
Secure stream encryption with native PHP.

PHP disables SSL/TLS peer verification by default. While this design decision significantly simplifies encrypted HTTP retrieval, it also means your transfers are totally vulnerable to Man-in-the-Middle attacks. To fully secure our transfers we need to verify that the party at the other end of our transfer is actually who they say they are.

To accomplish this we need two things:

  1. A CA file (in .PEM format) so we can tell openssl which certificate authorities we trust
  2. A stream context that specifies this CA file and instructs openssl to verify the other party

We can easily obtain the same CA file (direct link to .pem file) used by the Mozilla Foundation (the exact one cURL uses, BTW). This file is usually updated a handful of times each year and it's important to keep your CA file up-to-date or you risk trusting certificate authorities that are known to be insecure/unsafe. This kind of thing doesn't happen often, but it's important to update your CA file nonetheless.

Once you've stored the .pem CA file locally it's just a hop, skip and a jump to making secure https:// transfers with file_get_contents (or any other PHP stream functions):

<?php

// Change this to point to your newly downloaded CA file
$caFile = '/path/to/cacert.pem';

// Create a stream context to pass the relevant SSL information
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => TRUE,
    'cafile' => $caFile
]]);

$result = file_get_contents('https://github.com/', FALSE, $ctx);

If you've done something wrong the transfer will fail with an E_WARNING that looks something like this:

Warning: file_get_contents(): Failed to enable crypto in /var/my_ca.php on line 42

Otherwise, you're all set!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment