Book HomePHP CookbookSearch this book

14.10. Sharing Encrypted Data with Another Web Site

14.10.1. Problem

You want to securely exchange data with another web site.

14.10.2. Solution

If the other web site is pulling the data from your site, put the data up on a password-protected page. You can also make the data available in encrypted form, with or without a password. If you need to push the data to another web site, submit the potentially encrypted data via POST to a password-protected URL.

14.10.3. Discussion

The following page requires a username and password and then encrypts and displays the contents of a file containing yesterday's account activity:

$user = 'bank';
$password = 'fas8uj3';

if (! (($_SERVER['PHP_AUTH_USER'] == $user) && 
       ($_SERVER['PHP_AUTH_PW'] == $password))) {
    header('WWW-Authenticate: Basic realm="Secure Transfer"');
    header('HTTP/1.0 401 Unauthorized');
    echo "You must supply a valid username and password for access.";
    exit;
}

header('Content-type: text/plain');
$filename = strftime('/usr/local/account-activity.%Y-%m-%d',time() - 86400);
$data = join('',file($filename));

$alg  = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$key  = "There are many ways to butter your toast.";
 
// encrypt data
$iv = $iv = mcrypt_create_iv(mcrypt_get_iv_size($alg,$mode),
                             MCRYPT_DEV_URANDOM);
$ciphertext = mcrypt_encrypt($alg, $key, $data, $mode, $iv);

print base64_encode($iv.$ciphertext);

Here's the corresponding code to retrieve the encrypted page and decrypt the information:

$user = 'bank';
$password = 'fas8uj3';
$alg  = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$key  = "There are many ways to butter your toast.";

$fh = fopen("http://$user:$password@bank.example.com/accounts.php",'r') 
      or die($php_errormsg);
$data = '';
while (! feof($fh)) { $data .= fgets($fh,1048576); }
fclose($fh) or die($php_errormsg);
$binary_data = base64_decode($data);
$iv_size = mcrypt_get_iv_size($alg,$mode);
$iv = substr($binary_data,0,$iv_size);
$ciphertext = substr($binary_data,$iv_size,strlen($binary_data));

print mcrypt_decrypt($alg,$key,$ciphertext,$mode,$iv);

The retrieval program does all the steps of the encryption program but in reverse. It retrieves the Base64 encoded encrypted data, supplying a username and password. Then, it decodes the data with Base64 and separates out the initialization vector. Last, it decrypts the data and prints it out.

In the previous examples, the username and password are still sent over the network in clear text, unless the connections happen over SSL. However, if you're using SSL, it's probably not necessary to encrypt the file's contents. We included both password-prompting and file encryption in these examples to show how it can be done.

There's one circumstance, however, in which both password protection and file encryption is helpful: if the file isn't automatically decrypted when it's retrieved. An automated program can retrieve the encrypted file and put it, still encrypted, in a place that can be accessed later. The decryption key thus doesn't need to be stored in the retrieval program.

14.10.4. See Also

Recipe 8.10 for information on using HTTP Basic authentication; Recipe 14.11 discusses SSL and protecting data as it moves over the network; documentation on mcrypt_encrypt( ) at http://www.php.net/mcrypt-encrypt and mcrypt_decrypt( ) at http://www.php.net/mcrypt-decrypt.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.