Menu

Tuesday, November 6, 2012

Securing your data using PHP and OpenSSL


I saw that there wasn’t alot of information on the internet about how to encrypt data in your web application using php an openssl, so here it is.
First of all you need to understand how ssl connections works. If you already know that just skip this part:
The secured socket layer or ssl has many applications, but mostly it is used for creating an encrypted data tunnel between two remote machines.
1. The client application sends a handshake request to the remote server;
2. The server sends the ssl certificate information along with his public key;
3. The client application checks the hostname, expiration date, and authority registration of the certificate, and if some of these parameters is not met then a warning message is displayed to the user.
4. After receiving the public key form the server the client application generates an envelope key that is used to encrypt the data transfer between the two machines. This key is then encrypted with the server’s public key and send back to the server.
5. The envelope key can be decrypted only with the private key that server has.
6. After both machines have the envelope the data transfer can begin.

Although we won’t use any transfer protocol, we will do something very similar.
Lets start with openssl. OpenSSL is a command line tool that can help you generate your public and private keys needed for this example.
1. For generating public-private key pair, open a terminal and run:
# openssl genrsa -des3 -out certificate.pem 1024
You will be prompted for a passphrase. This passphrase will be used for decrypting the private key and it’s use is recommended.
After executing the command you should have a file named certificate.pem that should look like this:
—–BEGIN RSA PRIVATE KEY—–
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,3D2A826DAA45A4FD
oejviR8IoXgLnS3ZEC26vBt+IIlrRpvCn5R/JGm49UCEr5ItLdpWqQxib40IPgYu
f9nusVYKi2WLtCmtGKI7UcyZvZYOfksTbC6vzemorwcnkgBkWoLn1W/qyLaW2t6S
H4w+woz4hmak/VJJFBx2KGn9jWdC3rx4GdlNWJDLuzpa4ObUPgqClhLoBS2nXwWe
mjdrs7jNcz7CPXYTGhS5puAYzS6d8/0oJVBuZTtmXvJNU2TMwKcpmYMxJZ4ZBbR/
dfZyTq671i36ra3j7d7uSVRDlTFbd8708OalhRHxOuVHJKnd5H9N0AU8baXV6D0X
5EPMK8INiLZxtnZdc0zO7b+zOJ1f7ELL7g7Cwj8TzBJ8nT0yJCGnJWkp0ZpUGsOT
K9zeSApQgUWGj8ejaPOIkoqToNrSkiv/8/LzAkep37SBYpMdQf6sAuNDRYed+ktM
vsZYyOkNXXzxEUkPZsfzntGTDYypMJKX7FI4z8ovL5L+OPjrHIZVuNNrmgnOKs1E
KHCwQ0XQlPlK3/BC1TxB13PaSlf+/UGgzuQzl7gf6f48UMlOse0lhVzVj5U7zKhz
/ZAWg9oz0MjTXTccyQkuMMcrvOx9qN1o3YEuafcmDFK0CVkMvle53GvRzk+sVx76
UMO4/h6MrUo+WEslHbHgwOYrGCqw7xYRUhjUVY6/mthOeeJHg9uyMYyqWiyb0AE3
3ZSHVKkB9qjWCW8B74aW93XsV9oMungfLBBB8BC4c0NPBZVSSvZbmDWQOD0/qP6T
qYiffbW9kDwrjX2CnWccFk4o90XiAcP40GeLzna0xNRgsF+DL9o8kg==
—–END RSA PRIVATE KEY—–
2. Now we need to export the public key that will be used to encrypt our data. Run the following command:
# openssl rsa -in certificate.pem -pubout > public.key
You will be prompted for the passphrase that you’ve entered earlier.
Now we should have a file named public.key that looks like this:
—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0VfvEmljGvRQDmEPpy2UgsWsJ
d5kJJMmUENbeKquR8RDeZTKdLfO4Ts4cWucKOfJFREWgub1pf0ncZeyjZlkbPKEZ
wFT3ECrercmlK7QYZkh1R7AzPUxrj4foSP6EsvanxzFIQi2SkgNKLRyoRRfuMNaR
2/8P7Z3aKmnqhvse7wIDAQAB
—–END PUBLIC KEY—–
We can go ahead now and move the certificate.pem to a safe place where the apache user can’t access it.
Using openssl and php to encrypt and decrypt data.
There are three functions used in this example:
- openssl_seal() -> for encrypting data
openssl_open() -> for decrypting data
openssl_get_privatekey() -> for loading the private key

Encrypting data.

For the data encryption we need only the public key that we’ve created. Note that data encrypted with the public key can only be decrypted with it’s private key.
Code:
<?php
$publicKeyPath = ‘/path/public.key’;
$data = ‘I should be encrypted’;
$publicKey = array(file_get_contents($publicKeyPath));
$encData = null;
$envKey = null;
openssl_seal($data$encData$envKey$publicKey);
// as we use only one public key to encrypt data we will receive only one envelope key
$envKey = current($envKey);
var_dump($encData/*encrypted data*/$envKey/*envelope key*/);
?>
The data from this example can be then saved to the application’s database for future usage.

Decrypting data:

Code:
<?php
$privateKeyPath = ‘/path/certificate.pem’;
$passPhrase = ‘passphrese for decrypting the private key’;
$encData = ‘the encrypted data string’;
$envKey = ‘envelope key used for encryption’;
$privateKey = openssl_get_privatekey(file_get_contents($privateKeyPath), $passPhrase);
$data = null;
openssl_open($encData$data$envKey$privateKey);
var_dump($data);
?>
There are numerous ways of decrypting your data depending on the sensitivity level of the information. You can import the private key from a remote machine, use it in another system that will need the ability of reading this data or you can implement it on the same machine and application, wich is not recommended, beacause if an attacker has gained access to your system he can easily load your private key and access the information.


No comments:

Post a Comment