PHP Security and Encryption
Sharing Encrypted Data with Another Website
Problem
You want to exchange data securely with another website.
Solution
If the other website 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 website, submit the potentially encrypted data via post to a password-protected URL.
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; charset=UTF-8');
$filename = strftime('/usr/local/account-activity.%Y-%m-%d', time() - 86400);
$data = implode('', file($filename));
$algorithm = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$key = "There are many ways to butter your toast.";
/* Encrypt data. */
$iv = mcrypt_create_iv(mcrypt_get_iv_size($algorithm, $mode),
MCRYPT_DEV_URANDOM);
$ciphertext = mcrypt_encrypt($algorithm, $key, $data, $mode, $iv);
echo base64_encode($iv.$ciphertext);
Here’s the corresponding code to retrieve the encrypted page and decrypt the information:
$user = 'bank';
$password = 'fas8uj3';
$algorithm = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$key = "There are many ways to butter your toast.";
$url = 'https://bank.example.com/accounts.php';
$c = curl_init($url);
curl_setopt($c, CURLOPT_USERPWD, "$user:$password");
curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE);
$data = curl_exec($c);
if (FALSE === $data) {
exit("Transfer failed: " . curl_error($c));
}
$binary_data = base64_decode($data);
$iv_size = mcrypt_get_iv_size($algorithm, $mode);
$iv = substr($binary_data, 0, $iv_size);
$ciphertext = substr($binary_data, $iv_size, strlen($binary_data));
echo mcrypt_decrypt($algorithm, $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 contents of the file. 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.
No comments:
Post a Comment