PHP Symmetric Encryption Algorithm (DES and AES) class implementation code

  • 2021-08-12 02:19:09
  • OfStack

Symmetric key encryption mechanism is symmetric cryptosystem, which is also called single key cryptosystem and traditional cryptosystem. Symmetric cryptography is usually divided into two categories, one is block cipher (such as DES and AES algorithm), and the other is sequence cipher (such as RC4 algorithm).

AES is a new encryption algorithm that can be used to protect electronic data. Specifically, AES is an iterative, symmetric key packet cipher that can use 128, 192, and 256-bit keys and encrypt and decrypt data in 128-bit (16-byte) packets. Unlike public key cryptography, which uses key pairs, symmetric key cryptography uses the same key to encrypt and decrypt data. The number of bits of encrypted data returned by block cipher is the same as that of input data. Iterative encryption uses a loop structure in which replacement (permutations) and replacement (substitutions) input data are repeated. Figure 1 shows AES encrypting and decrypting a 16-bit byte data block with a 192-bit key.

What is DES? DES is called Data Encryption Standard, that is, data encryption standard. It is a block algorithm using key encryption. In 1977, it was identified as the Federal Data Processing Standard (FIPS) by the National Bureau of Standards of the federal government of the United States, and authorized to be used in non-confidential government communications. Subsequently, the algorithm has been widely spread in the world. It should be noted that in some literatures, DES as an algorithm is called a data encryption algorithm (Data, Encryption, Algorithm, DSA), which has been distinguished from DES as a standard.

In the design of DES, two principles of block cipher design are used: confusion (confusion) and diffusion (diffusion), which aims to resist the statistical analysis of the cryptosystem by adversaries. Confusion is to complicate the relationship between the statistical properties of the ciphertext and the value of the key as much as possible, so that the dependency between the key and plaintext and the ciphertext cannot be exploited by the cryptanalyzer. The function of diffusion is to spread the influence of every 1-bit plaintext to more output ciphertext bits as quickly as possible, so as to eliminate the statistical structure of plaintext in a large number of ciphertext, and to spread the influence of every 1-bit key to more ciphertext bits as quickly as possible, so as to prevent the key from being deciphered one by one.


/** 
 *  Common Symmetric Encryption Algorithm Classes  
 *  Support keys: 64/128/256 bit (Byte length) 8/16/32 )  
 *  Supporting algorithms: DES/AES Automatic matching based on key length uses: DES:64bit AES:128/256bit )  
 *  Support mode: CBC/ECB/OFB/CFB 
 *  Ciphertext encoding: base64 String /106 Binary string /2 Binary string stream  
 *  Filling mode : PKCS5Padding ( DES )  
 * 
 * @author: linvo 
 * @version: 1.0.0 
 * @date: 2013/1/10 
 */  
class Xcrypt{  
  
  private $mcrypt;  
  private $key;  
  private $mode;  
  private $iv;  
  private $blocksize;  
  
  /** 
   *  Constructor  
   * 
   * @param string  Key  
   * @param string  Mode  
   * @param string  Vector ( "off": Do not use  / "auto": Automatic  /  Others : Specify a value with the length of the key)  
   */  
  public function __construct($key, $mode = 'cbc', $iv = "off"){  
    switch (strlen($key)){  
    case 8:  
      $this->mcrypt = MCRYPT_DES;  
      break;  
    case 16:  
      $this->mcrypt = MCRYPT_RIJNDAEL_128;  
      break;  
    case 32:  
      $this->mcrypt = MCRYPT_RIJNDAEL_256;  
      break;  
    default:  
      die("Key size must be 8/16/32");  
    }  
  
    $this->key = $key;  
  
    switch (strtolower($mode)){  
    case 'ofb':  
      $this->mode = MCRYPT_MODE_OFB;  
      if ($iv == 'off') die('OFB must give a IV'); //OFB There must be vectors   
      break;  
    case 'cfb':  
      $this->mode = MCRYPT_MODE_CFB;  
      if ($iv == 'off') die('CFB must give a IV'); //CFB There must be vectors   
      break;  
    case 'ecb':  
      $this->mode = MCRYPT_MODE_ECB;  
      $iv = 'off'; //ECB Vectors are not required   
      break;  
    case 'cbc':  
    default:  
      $this->mode = MCRYPT_MODE_CBC;  
    }  
  
    switch (strtolower($iv)){  
    case "off":  
      $this->iv = null;  
      break;  
    case "auto":  
      $source = PHP_OS=='WINNT' ? MCRYPT_RAND : MCRYPT_DEV_RANDOM;  
      $this->iv = mcrypt_create_iv(mcrypt_get_block_size($this->mcrypt, $this->mode), $source);  
      break;  
    default:  
      $this->iv = $iv;  
    }  
  
  }  
  
  /** 
   *  Get Vector Values  
   * @param string  Vector-valued coding ( base64/hex/bin )  
   * @return string  Vector value  
   */  
  public function getIV($code = 'base64'){  
    switch ($code){  
    case 'base64':  
      $ret = base64_encode($this->iv);  
      break;  
    case 'hex':  
      $ret = bin2hex($this->iv);  
      break;  
    case 'bin':  
    default:  
      $ret = $this->iv;  
    }  
    return $ret;  
  }  
  
  /** 
   *  Encryption  
   * @param string  Cleartext  
   * @param string  Ciphertext encoding ( base64/hex/bin )  
   * @return string  Ciphertext  
   */  
  public function encrypt($str, $code = 'base64'){  
    if ($this->mcrypt == MCRYPT_DES) $str = $this->_pkcs5Pad($str);  
  
    if (isset($this->iv)) {  
      $result = mcrypt_encrypt($this->mcrypt, $this->key, $str, $this->mode, $this->iv);   
    } else {  
      @$result = mcrypt_encrypt($this->mcrypt, $this->key, $str, $this->mode);   
    }  
  
    switch ($code){  
    case 'base64':  
      $ret = base64_encode($result);  
      break;  
    case 'hex':  
      $ret = bin2hex($result);  
      break;  
    case 'bin':  
    default:  
      $ret = $result;  
    }  
  
    return $ret;  
  
  }  
  
  /** 
   *  Decryption   
   * @param string  Ciphertext  
   * @param string  Ciphertext encoding ( base64/hex/bin )  
   * @return string  Cleartext  
   */  
  public function decrypt($str, $code = "base64"){    
    $ret = false;  
  
    switch ($code){  
    case 'base64':  
      $str = base64_decode($str);  
      break;  
    case 'hex':  
      $str = $this->_hex2bin($str);  
      break;  
    case 'bin':  
    default:  
    }  
  
    if ($str !== false){  
      if (isset($this->iv)) {  
        $ret = mcrypt_decrypt($this->mcrypt, $this->key, $str, $this->mode, $this->iv);   
      } else {  
        @$ret = mcrypt_decrypt($this->mcrypt, $this->key, $str, $this->mode);   
      }  
      if ($this->mcrypt == MCRYPT_DES) $ret = $this->_pkcs5Unpad($ret);  
    }  
  
    return $ret;   
  }   
  
  private function _pkcs5Pad($text){  
    $this->blocksize = mcrypt_get_block_size($this->mcrypt, $this->mode);   
    $pad = $this->blocksize - (strlen($text) % $this->blocksize);  
    return $text . str_repeat(chr($pad), $pad);  
  }  
  
  private function _pkcs5Unpad($text){  
    $pad = ord($text{strlen($text) - 1});  
    if ($pad > strlen($text)) return false;  
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;  
    $ret = substr($text, 0, -1 * $pad);  
    return $ret;  
  }  
  
  private function _hex2bin($hex = false){  
    $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i', $hex) ? pack("H*", $hex) : false;    
    return $ret;  
  }  
  
}  

Use instances


<?php  
header('Content-Type:text/html;Charset=utf-8;');  
  
include "xcrypt.php";  
  
echo '<pre>';  
//////////////////////////////////////  
$a = isset($_GET['a']) ? $_GET['a'] : ' Test 123';  
  
// Key   
$key = '12345678123456781234567812345678'; //256 bit  
$key = '1234567812345678'; //128 bit  
$key = '12345678'; //64 bit  
  
// Set the mode and IV  
$m = new Xcrypt($key, 'cbc', 'auto');  
  
// Get Vector Values   
echo ' Vector: ';  
var_dump($m->getIV());  
  
// Encryption   
$b = $m->encrypt($a, 'base64');  
// Decryption   
$c = $m->decrypt($b, 'base64');  
  
echo ' After encryption: ';  
var_dump($b);  
echo ' After decryption: ';  
var_dump($c);  
  
/////////////////////////////////////////  
echo '</pre>'; 

Related articles: