使用 openssl 来加密
<?php
namespace addons\tsm\library;
use mysql_xdevapi\Exception;
class ThreeDesUtil
{
private static $Algorithm = 'DES-EDE3-CBC';
static function createKeyBytes($key){
$dest='';
$temp=self::hexStringToBytes($key);
try{
if(strlen($temp)<24){
$dest=substr($temp,0,strlen($temp));
$dest.=substr($temp,0,24-strlen($temp));
}
}catch (Exception $exception){
$exception->getTrace();
}
return $dest;
}
public static function encryptMode($key, $src, $iv){
try{
if(!is_null($src)&&!is_null($key)){
$result = openssl_encrypt(
self::hexStringToBytes($src),
self::$Algorithm,
self::createKeyBytes($key),
OPENSSL_NO_PADDING,
self::hexStringToBytes($iv)
);
return self::convertByteToHexString($result);
}else{
return 'KEY/内容为空';
}
}catch (Exception $exception){
$exception->getTrace();
}
return null;
}
public static function decryptMode($key,$src){
try{
if(!is_null($src)&&!is_null($key)){
$result=openssl_decrypt(self::hexStringToBytes($src),
self::$Algorithm,
self::createKeyBytes($key),
OPENSSL_NO_PADDING,
'');
return self::convertByteToHexString($result);
}else{
return 'KEY/内容为空';
}
}catch (Exception $exception){
$exception->getTrace();
}
}
private static function hexStringToBytes($hexString){
$len=strlen($hexString);
$buf=[];
$i=0;
$j=0;
if(($len%2)==1){
$buf[$j++]=chr(self::fromDigit($hexString[$i++]));
}
while ($i<$len){
$buf[$j++]=chr((self::fromDigit($hexString[$i++])<<4)|self::fromDigit($hexString[$i++]));
}
return implode($buf);
}
private static function convertByteToHexString($bytes){
$result='';
for ($i=0;$i<strlen($bytes);$i++){
$temp=ord($bytes[$i])&0xff;
$tempHex=dechex($temp);
if(strlen($tempHex)<2){
$result.='0'.$tempHex;
}else{
$result.=$tempHex;
}
}
return $result;
}
private static function fromDigit($ch){
if (ord($ch) >= ord('0') && ord($ch)<= ord('9')) {
return ord($ch) - ord('0');
}
if (ord($ch) >= ord('A') && ord($ch) <= ord('F')) {
return ord($ch) - ord('A') + 10;
}
if (ord($ch) >= ord('a') && ord($ch) <= ord('f')) {
return ord($ch) - ord('a') + 10;
}
throw new InvalidArgumentException('invalid hex digit:'.$ch);
}
public static function analogMacBy3Des($key, $data)
{
$iv = hex2bin('0000000000000000');
$data = hex2bin($data);
$key = hex2bin($key);
$leftKey = substr($key, 0, 8);
$rightKey = substr($key, 8, 8);
$result = openssl_encrypt($data, 'DES-CBC', $leftKey, OPENSSL_NO_PADDING, $iv);
$ecbDecryptData = substr($result, strlen($result)-8, strlen($result));
var_dump($ecbDecryptData);
$ecbDecryptReturn = openssl_decrypt($ecbDecryptData,'DES-ECB', $rightKey);
var_dump($ecbDecryptReturn);
$result = openssl_encrypt($ecbDecryptReturn, 'DES-ECB', $leftKey, OPENSSL_NO_PADDING);
return self::convertByteToHexString($result);
}
public static function calculatePboc3desMAC($data, $key, $iv)
{
$iv = hex2bin($iv);
$data = hex2bin($data);
$key = self::createKeyBytes($key);
if ($key == null || $data == null)
throw new RuntimeException("data or key is null.");
$leftKey = substr($key, 0, 8);;
$dataLength = strlen($data);
$blockCount = $dataLength / 8;
$lastBlockLength = $dataLength % 8;
$dataBlock = [];
for ($i = 0; $i < $blockCount; $i++) {
$copyLength = $i == $blockCount - 1 ? $lastBlockLength : 8;
$dataBlock[$i] = substr($data, $i*8, $copyLength);
}
if($lastBlockLength == 0) {
}else{
$blockCount = $blockCount +1;
$needLen = 8-$lastBlockLength-2;
$needHexData = bin2hex($dataBlock[$blockCount-1]).'80'.str_repeat('0', $needLen);
$dataBlock[$blockCount-1] = hex2bin($needHexData);
}
$iv = self::encryptByDesCbc($dataBlock[0], $leftKey, $iv);
if($blockCount > 2) {
for ($i = 1; $i < $blockCount; $i++) {
$iv = self::encryptByDesCbc($dataBlock[$i], $leftKey, $iv);
}
}
$desXor = self::encryptBy3DesCbc($dataBlock[$blockCount-1], $key, $iv);
return bin2hex($desXor);
}
public static function xor($binB1, $binB2)
{
$len = min(strlen($binB2),strlen($binB1)) ;
$xor = '';
for($i = 0; $i< $len; $i++) {
$xor .= substr($binB1, $i, 1) ^ substr($binB2, $i, 1);
}
return $xor;
}
public static function asc2bin($temp)
{
$len = strlen($temp);
$data ='';
for ($i = 0; $i < $len; $i++) {
$data .= sprintf('%08b', ord(substr($temp, $i, 1)));
}
return $data;
}
public static function encryptByDesCbc($data, $key, $iv)
{
$result = openssl_encrypt($data, 'des-cbc', $key, OPENSSL_NO_PADDING, $iv);
return $result;
}
public static function decryptByDesCbc($data, $key, $iv)
{
$result = openssl_decrypt($data, 'des-cbc', $key, OPENSSL_NO_PADDING, $iv);
return $result;
}
public static function encryptBy3DesCbc($data, $key, $iv)
{
$result = openssl_encrypt($data, 'DES-EDE3-CBC', $key, OPENSSL_NO_PADDING, $iv);
return $result;
}
public static function calculate3desMAC($data, $key)
{
$iv = hex2bin('0000000000000000');
$data = hex2bin($data);
$key = self::createKeyBytes($key);
if ($key == null || $data == null) {
return '';
}
$leftKey = substr($key, 0, 8);;
$dataLength = strlen($data);
$blockCount = $dataLength / 8 ;
$dataBlock = [];
$copyLength = 8;
for ($i = 0; $i < $blockCount; $i++) {
$dataBlock[$i] = substr($data, $i*8, $copyLength);
}
$des = self::encryptByDesCbc($dataBlock[0], $leftKey, $iv);
$des = self::encryptBy3DesCbc($dataBlock[1], $key, $des);
return bin2hex($des);
}
public static function getExternalAuthentication($hexData, $iv = '0000000000000000')
{
$VPENC = $VPMAC = $VPDEK = '404142434445464748494A4B4C4D4E4F';
$VSeqCounter = substr($hexData, 24, 4);
$VCardRandom = substr($hexData, 28, 12);
$VCardCrypt = substr($hexData, 40, 4);
$VSPENC_DerData = "0182".$VSeqCounter."000000000000000000000000";
$VSPMAC_DerData = "0101".$VSeqCounter."000000000000000000000000";
$VSPDEK_DerData = "0181".$VSeqCounter."000000000000000000000000";
$VSPENC = self::encryptMode($VPENC, $VSPENC_DerData, $iv);
$VSPMAC = self::encryptMode($VPMAC, $VSPMAC_DerData, $iv);
$VSPDEK = self::encryptMode($VPDEK, $VSPDEK_DerData, $iv);
$VDataforHostCrypt = $VSeqCounter.$VCardRandom.'0102030405060708'.'8000000000000000';
$VHostCrypt = self::encryptMode($VSPENC, $VDataforHostCrypt, $iv);
$VHostCrypt = substr($VHostCrypt, strlen($VHostCrypt)-16);
$VDataforCMAC = '8482'.'00'.'0010'.$VHostCrypt.'800000';
$VCMAC = ThreeDesUtil::calculate3desMAC($VDataforCMAC, $VSPMAC);
if(!$VCMAC) {
return '';
}
$VDataIn = $VHostCrypt.$VCMAC;
$apud = '8482000010'.$VDataIn;
return strtoupper($apud);
}
}
aes-128