Laboratory Exercise on Encryption in PHP
Goals
This laboratory exercise provides some practice in using encryption within
a database application.
Getting Started
This lab uses three HTML/PHP scripts as a base for exploration:
encryption-start.php,
encryption-action.php and decryption-action.php.
These scripts are available in directory
~walker/public_html/courses/325.fa08/examples/
-
Copy encryption-start.php,
encryption-action.php and decryption-action.php from
directory ~walker/public_html/courses/325.fa08/examples/
to a subdirectory of your public_html directory, and change the
permissions of these files to allow them to be executed.
-
Run encryption-start.php a few times to see how this sequence of
scripts works, and review the encryption/decryption steps in the code.
Some Details
As the accompanying scripts suggest, encryption/decryption in PHP is
reasonably straightforward. In addition to the data to be encrypted
(called the plain text message), specifics depend upon:
-
the encryption algorithm
-
a mode
-
an encryption key
-
an initialization vector
Normally, a particular script or application will determine the encryption
algorithm and mode, and these will be hard-coded within PHP programs. But
how should we handle the encryption key and initialization vector?
Storing Keys and Initialization Vectors
Encryption keys and initialization vectors can be stored following two
basic approaches. Each has both advantages and disadvantages:
-
We can choose one string for the application.
-
Advantages:
-
The key or initialization vector must only be computed once, perhaps as
part of program development.
-
A common key or initialization vector must only be stored once, perhaps in
a variable-initialization file (e.g., key = "...").
-
Programming is relatively simple, since the preliminaries of encryption and
decryption are always the same.
-
Disadvantages:
-
If a data item is common to two records, the encrypted version will be the
same in each case. Thus, if someone can view multiple records, the person
might see patterns or make inferences about data — even without
knowing just what the data mean.
-
We can change the string for each user/data item.
-
Advantages:
-
Each data record is encoded in a different way, so viewing multiple records
does not allow an intruder to identify patterns.
-
Access to one data item (after decryption) does not provide much guidance
about other data items.
-
Disadvantages:
-
The key and/or initialization vectors for each item must be stored somewhere.
-
The key and/or initialization vectors must be recomputed or retrieved for
each record.
Note: As noted in the class examples for encryption,
the Linux operating system stores a separate salt for each username in a
public password file. Thus, Linux follows the second approach above,
although the password application utilizes one-way encryption only —
Linux provides no mechanism for decrypting passwords to get plain text back.
Assumptions for this Lab
In the rest of this laboratory exercise, we use a separate key and
initialization vector for each record:
-
The key will be computed from a username, as illustrated in the
class examples.
-
The key and the initialization vector will be stored in the database within
the same record as the data (not really a good strategy, but possibly
acceptable for this exercise).
More specifically, this lab will store encrypted data in a table
sampleEncryptedData, defined as follows:
create table sampleEncryptedData (
recordID bigint(20) unsigned not null auto_increment,
username varchar(25),
initVector tinyblob, /* binary field up to 255 bytes */
encMessage blob, /* binary field up to 65,535 bytes */
primary key (recordID)
);
Notes
-
Since SQL statements consider some characters (e.g., quotes) as having
special meanings, one must scan any string before inserting it
into the database, adding various escape characters as needed. PHP
function mysql_real_escape_string can help, as illustrated at the
end of the sample script encryption-action.php.
-
Sometimes it can be useful to insert a record into a database and then
determine the record number (based on an auto_increment field). This can be
accomplished with the PHP function mysql-insert-id()
Lab Activities
-
Modify encryption-start.php, so that it has two sections:
-
An encryption section is about the same as the current
encryption-start.php; the page asks for a text, username,
encryption algorithm, and mode. Clicking submit goes to
encryption-action.php
-
A decryption section asks for a username, encryption algorithm, and mode.
clicking submit goes to decryption-action.php
-
Modify encryption-action.php, so that it proceeds as follows:
-
encryption-action.php generates a key, as illustrated in the
current version of this script.
-
The script determines the initialization vector:
-
If the username is already available within table
sampleEncryptedData, the script retrieves the initialization
vector from the table.
-
If the username is not in table encryption-action.php,
the script generates a new initialization vector.
-
With the computed key and the determined initialization vector, the script
encrypts the message.
-
The script stores the relevant data within table
sampleEncryptedData.
-
If the username was not previously in the database, a new record is created
to contain the username, initialization vector, and encrypted message.
-
If the username was already in the database, only the encrypted message
field for that username is updated.
-
Modify decryption-action.php, so that it proceeds as follows:
-
decryption-action.php retrieves the record for the given username
from table sampleEncryptedData.
-
The script computes the relevant key from the username, as illustrated in the
current version of this script.
-
The script decrypts the encoded message with the computed key and retrieved
initialization vector.
-
The script prints the decrypted message to the screen.
Work to Turn In
-
Listings of scripts for steps 3, 4, 5.
-
URL for the directory for these three scripts.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~walker/courses/325.fa08/lab-encrytion.shtml