Master PHP Encryption: From MD5 to OpenSSL Asymmetric Techniques
This article explains PHP's various encryption methods, covering one-way hash functions like MD5 and SHA1, symmetric algorithms, the rarely used crypt() function, and detailed implementations of asymmetric encryption with OpenSSL, including key generation, encryption, decryption, and practical code examples.
Information Encryption Techniques in PHP
During an interview I was asked about classic asymmetric encryption algorithms, but I confused them with one‑way hash functions. This article clarifies the different categories of encryption techniques available in PHP.
One‑Way Hash Functions (Irreversible)
MD5 string md5 ( string $str [, bool $raw_output = false ] ); MD5 produces a 32‑character hash. It is not reversible, but common passwords can be cracked via dictionary or rainbow‑table attacks. Adding a random salt and double‑hashing makes cracking harder, e.g.: md5(md5($password).'sdva'); crypt
The crypt() function can be used with custom salts. Example:
<?php
$password='testtest.com';
echo crypt($password);
// output: $1$DZ3.QX2.$CQZ8I.OfeepKYrWp0oG8L1
?>Providing a custom salt (e.g., crypt($password,'testtest')) uses the MD5‑based salt format $1$testtest$.
SHA1 Hash
string sha1 ( string $str [, bool $raw_output = false ] );SHA1 returns a 40‑character hash. It can be combined with MD5 for double hashing:
<?php
$my_intro="zhouxiaogang";
echo sha1($my_intro); // b6773e8c180c693d9f875bcf77c1202a243e8594
echo md5(sha1($my_intro)); // 54818bd624d69ac9a139bf92251e381d
?>Asymmetric Encryption
Asymmetric encryption uses a public key and a private key. The typical workflow is:
Party B generates a key pair and publishes the public key.
Party A encrypts data with B’s public key and sends it.
Party B decrypts with its private key.
Even if an attacker intercepts the ciphertext and knows the public key, decryption is impossible without the private key.
Common asymmetric algorithms include RSA, ElGamal, Rabin, Diffie‑Hellman, and ECC. RSA is the most widely used.
Example of RSA implementation with OpenSSL in PHP:
<?php
class Rsa {
private $_privKey;
private $_pubKey;
private $_keyPath;
public function __construct($path) {
if (empty($path) || !is_dir($path)) {
throw new Exception('Must set the keys save path');
}
$this->_keyPath = $path;
}
public function createKey() {
$r = openssl_pkey_new();
openssl_pkey_export($r, $privKey);
file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key', $privKey);
$this->_privKey = openssl_pkey_get_private($privKey);
$rp = openssl_pkey_get_details($r);
$pubKey = $rp['key'];
file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key', $pubKey);
$this->_pubKey = openssl_pkey_get_public($pubKey);
}
public function setupPrivKey() {
if (is_resource($this->_privKey)) return true;
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key';
$prk = file_get_contents($file);
$this->_privKey = openssl_pkey_get_private($prk);
return true;
}
public function setupPubKey() {
if (is_resource($this->_pubKey)) return true;
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key';
$puk = file_get_contents($file);
$this->_pubKey = openssl_pkey_get_public($puk);
return true;
}
public function privEncrypt($data) {
if (!is_string($data)) return null;
$this->setupPrivKey();
$r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
return $r ? base64_encode($encrypted) : null;
}
public function privDecrypt($encrypted) {
if (!is_string($encrypted)) return null;
$this->setupPrivKey();
$encrypted = base64_decode($encrypted);
$r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
return $r ? $decrypted : null;
}
public function pubEncrypt($data) {
if (!is_string($data)) return null;
$this->setupPubKey();
$r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
return $r ? base64_encode($encrypted) : null;
}
public function pubDecrypt($crypted) {
if (!is_string($crypted)) return null;
$this->setupPubKey();
$crypted = base64_decode($crypted);
$r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
return $r ? $decrypted : null;
}
public function __destruct() {
@fclose($this->_privKey);
@fclose($this->_pubKey);
}
}
?>Simple test demo:
<?php
$rsa = new Rsa('ssl-key');
// Private key encrypt, public key decrypt
$pre = $rsa->privEncrypt('我是老鳖');
echo 'private encrypted:<br>' . $pre . '<br>';
$pud = $rsa->pubDecrypt($pre);
echo 'public decrypted:' . $pud . '<br>';
// Public key encrypt, private key decrypt
$pue = $rsa->pubEncrypt('干IT的');
echo 'public encrypt:<br>' . $pue . '<br>';
$prd = $rsa->privDecrypt($pue);
echo 'private decrypt:' . $prd;
?>Symmetric Encryption
Symmetric (private‑key) encryption uses the same secret key for encryption and decryption. Common algorithms include DES, 3DES, TDEA, Blowfish, RC5, and IDEA. PHP provides built‑in functions such as urlencode/urldecode (which are encoding rather than true encryption) and base64_encode/base64_decode (also encoding).
Example of using urlencode to safely embed special characters in URLs:
<?php
$username = "zhou&gang";
$url = "zhougang.com?username=" . urlencode($username) . "&password=zhou";
?>Discuz Classic Algorithm (authcode)
Discuz implements a custom reversible encryption function authcode() that uses a dynamic key, MD5, and a pseudo‑random key‑schedule. The source code is provided in the article.
General Encrypt/Decrypt Function
A generic encrypt() function is shown, supporting both encryption (operation ‘E’) and decryption (operation ‘D’) with optional key, MD5‑based integrity check, and RC4‑style stream cipher.
<?php
function encrypt($string,$operation,$key=''){
$key=md5($key);
$key_length=strlen($key);
$string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;
$string_length=strlen($string);
$rndkey=$box=array();
$result='';
for($i=0;$i<=255;$i++){
$rndkey[$i]=ord($key[$i%$key_length]);
$box[$i]=$i;
}
for($j=$i=0;$i<256;$i++){
$j=($j+$box[$i]+$rndkey[$i])%256;
$tmp=$box[$i];
$box[$i]=$box[$j];
$box[$j]=$tmp;
}
for($a=$j=$i=0;$i<$string_length;$i++){
$a=($a+1)%256;
$j=($j+$box[$a])%256;
$tmp=$box[$a];
$box[$a]=$box[$j];
$box[$j]=$tmp;
$result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
}
if($operation=='D'){
if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))
return substr($result,8);
else
return '';
}else{
return str_replace('=','',base64_encode($result));
}
}
?>The article concludes with a reference to the original CNBlogs source.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
