对于加解密,企业常用的有AES和RSA,它们分别是对称加解密算法和非对称加解密算法的代表,这里主要封装了php的一套基于openssl的AES加解密实现类
<?php
/**
* Created by PhpStorm.
* User: 小小徐
* Date: 2019/4/21
* Time: 18:11
*/
class BaseAES{
/**
* 初始化向量长度|随机向量长度
*/
const INIT_VECTOR_LENGTH = 16;
/**
* 常见的的两种AES加密128|256
*/
const CIPHER128 = 'AES-128-CBC';
const CIPHER256 = 'AES-256-CBC';
/**
* @var string 加解密方式
*/
protected static $method ;
/**
* 加密|解密字符
* @var null|string
*/
protected $data;
/**
* 随机偏移量
* @var string
*/
protected $initVector;
/**
* 错误信息
* @var null|string
*/
protected $errorMessage;
/**
* 构造函数
* @param string $initVector 偏移量
* @param string|null $data 加解密数据
* @param string|null $errorMessage 错误信息
*/
public function __construct($initVector, $data = null, $errorMessage = null)
{
$this->initVector = $initVector;
$this->data = $data;
$this->errorMessage = $errorMessage;
}
/**
* 校验密钥长度
* @param string $secretKey 16/24/32 -characters secret password
* @return bool
*/
protected static function isKeyLengthValid($secretKey)
{
$length = strlen($secretKey);
return $length == 16 || $length == 24 || $length == 32;
}
/**
* 获取加解密的字符串
* @return string|null
*/
public function getData()
{
return $this->data;
}
/**
* 获取随机偏移量
* @return string|null
*/
public function getInitVector()
{
return $this->initVector;
}
/**
* 获取错误信息
* @return string|null
*/
public function getErrorMessage()
{
return $this->errorMessage;
}
/**
* 判断是否有错误
* @return bool
*/
public function hasError()
{
return $this->errorMessage !== null;
}
/**
* @return null|string
*/
public function __toString()
{
return $this->getData();
}
/**
* 基于openssl的解密方法
* @param string $plainText 需要解密的字符串
* @param string $secretKey 密钥长度16|24|32
* @param string $initVector 偏移量
* @param string $method 解密方式
* @return static
*/
public static function decrypt($cipherText, $secretKey,$initVector=null, $method= null)
{
try {
// 校验密钥长度
if (!static::isKeyLengthValid($secretKey)) {
throw new \InvalidArgumentException("Secret key's length must be 128, 192 or 256 bits");
}
// 获取原加密后的字符串
$encoded = base64_decode($cipherText);
//获取解密方式
if(null === $method){
$method = self::CIPHER128;
}
// 获取真正加密后的原始串
$data = static ::decryptCallBack($initVector,$encoded);
// 解密
$decoded = openssl_decrypt(
$data,
$method,
$secretKey,
OPENSSL_RAW_DATA,
$initVector
);
if ($decoded === false) {
// Operation failed
return new static(isset($initVector), null, openssl_error_string());
}
// 返回一个自己的对象 可以再进行进一步操作
return new static($initVector, $decoded);
} catch (\Exception $e) {
// Operation failed
return new static(isset($initVector), null, $e->getMessage());
}
}
/**
* 基于openssl的加密方法
* @param string $plainText 需要加密的字符串
* @param string $secretKey 密钥长度16|24|32
* @param string $initVector 偏移量
* @param string $method 加密方式
* @return static
*/
protected static function encrypt($plainText, $secretKey,$initVector=null, $method= null)
{
try {
//校验密钥长度
if (!static::isKeyLengthValid($secretKey)) {
throw new \InvalidArgumentException("Secret key's length must be 128, 192 or 256 bits");
}
//设置加密方式
if(null === $method){
$method = self::CIPHER128;
}
// 生成随机向量 即偏移量
if(null === $initVector){
$initVector = bin2hex(openssl_random_pseudo_bytes(static::INIT_VECTOR_LENGTH / 2));
}
//加密
$raw = openssl_encrypt(
$plainText,
$method,
$secretKey,
OPENSSL_RAW_DATA,
$initVector
);
//对加密后的原始数据和偏移量进行操作
$callBackResult = static ::encryptCallBack($initVector,$raw);
// Return base64-encoded string: $callBackResult result |将数据进行base64_encode
$result = base64_encode($callBackResult);
if ($result === false) {
// Operation failed
return new static($initVector, null, openssl_error_string());
}
// 返回自己的对象方便进一步操作
return new static($initVector, $result);
} catch (\Exception $e) {
// Operation failed
return new static(isset($initVector), null, $e->getMessage());
}
}
/**
* 与decryptCallBack相对应
* 在加密后和base64_encode之前 对 加密后的原始数据与偏移量进行操作
* @param $initVector string 偏移量
* @param $raw string 加密后的原始串[非utf8]
* @return string
*/
protected static function encryptCallBack($initVector,$raw){
return $initVector.$raw;
}
/**
* 与encryptCallBack相对应
* 在base64_decode之后和解密之前 对 需要解密的字符串进行base64_decode之后的原始数据与偏移量进行操作
* @param $initVector string 偏移量
* @param $encoded string 解密后的原始串[非utf8]
* @return bool|string
*/
protected static function decryptCallBack(&$initVector,$encoded){
// 获取偏移量
if( null === $initVector){
$initVector = substr($encoded, 0, static::INIT_VECTOR_LENGTH);
}
return substr($encoded, static::INIT_VECTOR_LENGTH);
}
/**
* AES128加密
* @param $plainText string 需要加密的字符串
* @param $secretKey string 密钥
* @param $initVector string 偏移量
* @return BaseAES
*/
public static function encryptWith128CBC($plainText, $secretKey,$initVector=null)
{
return self::encrypt($plainText,$secretKey,$initVector);
}
/**
* AES128解密
* @param $cipherText string 需要解密的字符串
* @param $secretKey string 密钥
* @param $initVector string 偏移量
*/
public static function decryptWith128CBC($cipherText, $secretKey,$initVector=null)
{
return self::decrypt($cipherText, $secretKey,$initVector);
}
/**
* AES256加密
* @param $plainText string 需要加密的字符串
* @param $secretKey string 密钥
* @param $initVector string 偏移量
* @return BaseAES
*/
public static function encryptWith256CBC($plainText, $secretKey,$initVector=null)
{
return self::encrypt($plainText,$secretKey,$initVector,self::CIPHER256);
}
/**
* AES256解密
* @param $cipherText string 需要解密的字符串
* @param $secretKey string 密钥
* @param $initVector string 偏移量
*/
public static function decryptWith256CBC($cipherText, $secretKey,$initVector=null)
{
return self::decrypt($cipherText, $secretKey,$initVector,self::CIPHER256);
}
}
使用方式
$key = 'zxcvbnmasdfghjkl';
$data = "who are you!";
$res1 = BaseAES::encryptWith256CBC($data,$key);
$res2 = BaseAES::decryptWith256CBC($res1,$key);
var_dump($res1);
var_dump($res2);
为了满足更特殊的需求,返回的是一个对象,包含加密|解密的数据及随机生成的偏移量以满足特殊的使用场景