In this article I’ll will walk you through the basic encryption and decryption of a string using AES-256 algorithm. AES, known as Rijndael, is an advanced encryption algorithm. Due to the complexity and security provided it is widely used. Choosing the best encryption method is a complex topic and it will not be covered in this article. As a source of inspiration we’ll take the CakePHP Security class.

Choosing a private key

A private key is a random generated string kept on the server side. This means that only the ones who have access to the source files will know the private key. Private key is static and it won’t change it’s value. A good random private key can be obtain here: 40 Characters Long (Good for Cakephp Security Salt).

Encrypt a string in PHP

For the encryption function we’ll use AES-256 algorithm. We’ll achieve the desired result with the PHP Mycrypt library. Depending on your server configuration you may need to install this library.
public static function encrypt($plain, $key = null, $hmacSalt = null) {
	if(empty($key)) {
		$key = self::$salt;
	}
	
        self::_checkKey($key, 'encrypt()');
 
        if ($hmacSalt === null) {
            $hmacSalt = self::$salt;
        }
 
        $key = substr(hash('sha256', $key . $hmacSalt), 0, 32); # Generate the encryption and hmac key
 
        $algorithm = MCRYPT_RIJNDAEL_128; # encryption algorithm
        $mode = MCRYPT_MODE_CBC; # encryption mode
 
        $ivSize = mcrypt_get_iv_size($algorithm, $mode); # Returns the size of the IV belonging to a specific cipher/mode combination
        $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM); # Creates an initialization vector (IV) from a random source
        $ciphertext = $iv . mcrypt_encrypt($algorithm, $key, $plain, $mode, $iv); # Encrypts plaintext with given parameters
        $hmac = hash_hmac('sha256', $ciphertext, $key); # Generate a keyed hash value using the HMAC method
        return $hmac . $ciphertext;
}

Decrypt a string in PHP

Because we’re not using a one way encryption method like MD5, SHA1 or SHA2 we want to decrypt information if we have all the required pieces: private key and encrypted data.
 public static function decrypt($cipher, $key = null, $hmacSalt = null) {
        if(empty($key)) {
			$key = self::$salt;
		}
		
		self::_checkKey($key, 'decrypt()');
		if (empty($cipher)) {
			echo 'The data to decrypt cannot be empty.'; die();
		}
		if ($hmacSalt === null) {
			$hmacSalt = self::$salt;
		}

		$key = substr(hash('sha256', $key . $hmacSalt), 0, 32); # Generate the encryption and hmac key.

		# Split out hmac for comparison
		$macSize = 64;
		$hmac = substr($cipher, 0, $macSize);
		$cipher = substr($cipher, $macSize);

		$compareHmac = hash_hmac('sha256', $cipher, $key);
		if ($hmac !== $compareHmac) {
			return false;
		}

		$algorithm = MCRYPT_RIJNDAEL_128; # encryption algorithm
		$mode = MCRYPT_MODE_CBC; # encryption mode
		$ivSize = mcrypt_get_iv_size($algorithm, $mode); # Returns the size of the IV belonging to a specific cipher/mode combination

		$iv = substr($cipher, 0, $ivSize);
		$cipher = substr($cipher, $ivSize);
		$plain = mcrypt_decrypt($algorithm, $key, $cipher, $mode, $iv);
		return rtrim($plain, "\0");
	}

Conclusions and wrapped code

Even if you are using an advanced encryption algorithm like AES-256 (AES is a specification for the encryption of electronic data established by the U.S. NITS in 2001 - source) you need to plus with additional security patches in order to pass an encrypted information through the cloud like: using a https connection, block malicious users against force brute attacks or accept the encrypted value only one time (prevent Man-in-the-middle attack).
<?php class Security {
     
    # Private key
    public static $salt = 'ZfTfbip&Gs0Z4yz34jFrG)Ha0gahptzLN7ROi%gy';
 
 
    # Encrypt a value using AES-256.
    public static function encrypt($plain, $key = null, $hmacSalt = null) {
		if(empty($key)) {
			$key = self::$salt;
		}
	
        self::_checkKey($key, 'encrypt()');
 
        if ($hmacSalt === null) {
            $hmacSalt = self::$salt;
        }
 
        $key = substr(hash('sha256', $key . $hmacSalt), 0, 32); # Generate the encryption and hmac key
 
        $algorithm = MCRYPT_RIJNDAEL_128; # encryption algorithm
        $mode = MCRYPT_MODE_CBC; # encryption mode
 
        $ivSize = mcrypt_get_iv_size($algorithm, $mode); # Returns the size of the IV belonging to a specific cipher/mode combination
        $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM); # Creates an initialization vector (IV) from a random source
        $ciphertext = $iv . mcrypt_encrypt($algorithm, $key, $plain, $mode, $iv); # Encrypts plaintext with given parameters
        $hmac = hash_hmac('sha256', $ciphertext, $key); # Generate a keyed hash value using the HMAC method
        return $hmac . $ciphertext;
    }
 
    # Check key
    protected static function _checkKey($key, $method) {
        if (strlen($key) < 32) {
            echo "Invalid key $key, key must be at least 256 bits (32 bytes) long."; die();
        }
    }
 
    # Decrypt a value using AES-256.
    public static function decrypt($cipher, $key = null, $hmacSalt = null) {
        if(empty($key)) {
			$key = self::$salt;
		}
		
		self::_checkKey($key, 'decrypt()');
		
        if (empty($cipher)) {
            echo 'The data to decrypt cannot be empty.'; die();
        }
        if ($hmacSalt === null) {
            $hmacSalt = self::$salt;
        }
 
        $key = substr(hash('sha256', $key . $hmacSalt), 0, 32); # Generate the encryption and hmac key.
 
        # Split out hmac for comparison
        $macSize = 64;
        $hmac = substr($cipher, 0, $macSize);
        $cipher = substr($cipher, $macSize);
 
        $compareHmac = hash_hmac('sha256', $cipher, $key);
        if ($hmac !== $compareHmac) {
            return false;
        }
 
        $algorithm = MCRYPT_RIJNDAEL_128; # encryption algorithm
        $mode = MCRYPT_MODE_CBC; # encryption mode
        $ivSize = mcrypt_get_iv_size($algorithm, $mode); # Returns the size of the IV belonging to a specific cipher/mode combination
 
        $iv = substr($cipher, 0, $ivSize);
        $cipher = substr($cipher, $ivSize);
        $plain = mcrypt_decrypt($algorithm, $key, $cipher, $mode, $iv);
        return rtrim($plain, "\0");
    }    
 
}
 
$security = new Security();
 
$string = "Our precious information";

$encryptedData = $security->encrypt($string);
echo "Encrypted data: $encryptedData <hr/>";
 
$decryptedData = $security->decrypt($encryptedData);
echo "Decrypted data: $decryptedData <hr/>";
 
$encodedData = rawurlencode($encryptedData);
$url = "?data={$encodedData}";
echo "<a href='{$url}'>Send encrypted data over the internet</a><hr/>";
if(isset($_GET['data'])) { # If we have received some data 
    $dataArr = explode('&', $_SERVER['QUERY_STRING']); # because php auto decodes $_GET and it's having problem with UTF values
     
    foreach($dataArr as $key=>$value) {
        $aux = explode('=', $value);
        $_GET[$aux[0]] = $aux[1]; # regenerate $_GET with undecoded values
    }     
  
    $data = rawurldecode($_GET['data']);
     
    $data = $security->decrypt($data);
    echo "I received an encrypted data: ";
    echo $data?$data:"I cannot decrypt it: $data";
}

Online demo for encrypt and decrypt data in php using this code

Demo