Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two-way encryption in PHP

Tags:

php

encryption

My application (obviously) uses a unique ID to distinguish records. This UID is passed in URLs (e.g. ./examplepage.php?UID=$example_int), among other things.

While I obviously have server-side validation in place to make sure clients don't access other clients' data, is there a two-way encryption method I can use in PHP to only pass encrypted UIDs (e.g. ./examplepage.php?EUID=$encrypted_int), to further reduce the chance of anyone thinking "hey, what happens if I increment this integer?"

TIA.

like image 354
benjy Avatar asked Sep 07 '09 22:09

benjy


People also ask

What is a two-way encryption?

Encryption is a two-way function where data is passed in as plaintext and comes out as ciphertext, which is unreadable. Since encryption is two-way, the data can be decrypted so it is readable again.

What is the best way to encrypt password in PHP?

Luckily, PHP makes this easy thanks to password_hash() . $hash = password_hash($password, PASSWORD_DEFAULT); The password_hash() function not only uses a secure one-way hashing algorithm, but it automatically handles salt and prevents time based side-channel attacks.

How do you use encrypt and decrypt in PHP?

In PHP, Encryption and Decryption of a string is possible using one of the Cryptography Extensions called OpenSSL function for encrypt and decrypt. openssl_encrypt() Function: The openssl_encrypt() function is used to encrypt the data. Parameters: $data: It holds the string or data which need to be encrypted.


2 Answers

PHP 5.3 has introduced a new encryption method that is really easy to use: openssl_encrypt and openssl_decrypt. It's not well-documented here, so here's a simple example:

$textToEncrypt = "My super secret information."; $encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents. $secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";  //To encrypt $encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash);  //To Decrypt $decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);  //Result echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage"; 

I chose 256-AES because it's solid and fast. It's been adopted by the U.S. gov't to encrypt top secret documents. It's fast considering machine and software. Here's a list of available encryption methods:

AES-128-CBC, AES-128-CFB, AES-128-CFB1, AES-128-CFB8, AES-128-ECB, AES-128-OFB, AES-192-CBC, AES-192-CFB, AES-192-CFB1, AES-192-CFB8, AES-192-ECB, AES-192-OFB, AES-256-CBC, AES-256-CFB, AES-256-CFB1, AES-256-CFB8, AES-256-ECB, AES-256-OFB, BF-CBC, BF-CFB, BF-ECB, BF-OFB, CAMELLIA-128-CBC, CAMELLIA-128-CFB, CAMELLIA-128-CFB1, CAMELLIA-128-CFB8, CAMELLIA-128-ECB, CAMELLIA-128-OFB, CAMELLIA-192-CBC, CAMELLIA-192-CFB, CAMELLIA-192-CFB1, CAMELLIA-192-CFB8, CAMELLIA-192-ECB, CAMELLIA-192-OFB, CAMELLIA-256-CBC, CAMELLIA-256-CFB, CAMELLIA-256-CFB1, CAMELLIA-256-CFB8, CAMELLIA-256-ECB, CAMELLIA-256-OFB, CAST5-CBC, CAST5-CFB, CAST5-ECB, CAST5-OFB, DES-CBC, DES-CFB, DES-CFB1, DES-CFB8, DES-ECB, DES-EDE, DES-EDE-CBC, DES-EDE-CFB, DES-EDE-OFB, DES-EDE3, DES-EDE3-CBC, DES-EDE3-CFB, DES-EDE3-CFB1, DES-EDE3-CFB8, DES-EDE3-OFB, DES-OFB, DESX-CBC, RC2-40-CBC, RC2-64-CBC, RC2-CBC, RC2-CFB, RC2-ECB, RC2-OFB, RC4, RC4-40, SEED-CBC, SEED-CFB, SEED-ECB, SEED-OFB, aes-128-cbc, aes-128-cfb, aes-128-cfb1, aes-128-cfb8, aes-128-ecb, aes-128-ofb, aes-192-cbc, aes-192-cfb, aes-192-cfb1, aes-192-cfb8, aes-192-ecb, aes-192-ofb, aes-256-cbc, aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-ecb, aes-256-ofb, bf-cbc, bf-cfb, bf-ecb, bf-ofb, camellia-128-cbc, camellia-128-cfb, camellia-128-cfb1, camellia-128-cfb8, camellia-128-ecb, camellia-128-ofb, camellia-192-cbc, camellia-192-cfb, camellia-192-cfb1, camellia-192-cfb8, camellia-192-ecb, camellia-192-ofb, camellia-256-cbc, camellia-256-cfb, camellia-256-cfb1, camellia-256-cfb8, camellia-256-ecb, camellia-256-ofb, cast5-cbc, cast5-cfb, cast5-ecb, cast5-ofb, des-cbc, des-cfb, des-cfb1, des-cfb8, des-ecb, des-ede, des-ede-cbc, des-ede-cfb, des-ede-ofb, des-ede3, des-ede3-cbc, des-ede3-cfb, des-ede3-cfb1, des-ede3-cfb8, des-ede3-ofb, des-ofb, desx-cbc, rc2-40-cbc, rc2-64-cbc, rc2-cbc, rc2-cfb, rc2-ecb, rc2-ofb, rc4, rc4-40, seed-cbc, seed-cfb, seed-ecb, seed-ofb


IMPORTANT UPDATE!!!

Thanks Hobo and Jorwin for pointing out that in PHP 5.3.3 > there is a new parameter that makes this function a little more secure.

Jorwin referenced this link in his comment, and here is an excerpt that is applicable:

In 5.3.3 they added a new parameter, string $iv (initialization vector) Real parameters are: string openssl_encrypt ( string $data , string $method , string $password, bool $raw_output = false, string $iv )

If $iv is missing, a warning is issued: "Using an empty Initialization Vector (iv) is potentially insecure and not recommended".

If $iv is too short, another warning: "IV passed is only 3 bytes long, cipher expects an IV of precisely 8 bytes, padding with \0"

same IV should be used in openssl_decrypt()

like image 167
espradley Avatar answered Oct 12 '22 11:10

espradley


You don't need two-way encryption - encryption is for maintaining secrecy, but what you're really looking for here is authenticity.

HMACs (essentially, keyed hashes) are one way of getting cryptographic authenticity. Accompany the UID with a HMAC of the UID (PHP has a HMAC implementation), using a key that only the server knows. At the start of each request, check the HMAC.

Basically, use the right tool for the right job.

like image 33
caf Avatar answered Oct 12 '22 09:10

caf