基于标准的CBC模式的DES加密算法

作者:谢高升 发布:2017-07-06 浏览:4918次

a)采用标准的CBC模式的DES加密算法;

b)密钥长度为56位,唯一密钥;

c)数据采用初始向量(VI)做互斥运算,VI唯一初始向量;

d)所有协议数据的明文需要在尾部加上原始数据长度,再加上“ABCD”4个字母,然后按64位进行分组,不足64位的以“\0”补足,分组后的明文采用统一的加密方式生成密文,即采用 “明文+密钥+初始化向量(VI)”。

e) 加密结果先base64_encode 然后urlencode加密

<?php

header("Content-type:text/html;charset=utf-8");
//加密
function encrypt($str , $key , $iv) {
	return @mcrypt_cbc(MCRYPT_DES, $key, $str, MCRYPT_ENCRYPT, $iv );
}
//解密
function decrypt($strBin , $key = '12345678',$iv = '12345678'){
    $strBin = base64_decode(urldecode($strBin));//解密的时候要先urldecode 在base64和加密相反

	return @mcrypt_cbc( MCRYPT_DES, $key, $strBin, MCRYPT_DECRYPT, $iv );
}


 //发送http 请求
function postUrl($url , $data){
	$ch = curl_init();     
	curl_setopt($ch, CURLOPT_URL, $url);    
	curl_setopt($ch, CURLOPT_POST, true);     
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     
	$handles = curl_exec($ch);     
	curl_close($ch);
	return $handles;
}

//这是在尾部添加的数据;如果有错误的话会使解密的数据和加密的数据开头有乱码
function getnbytes($data,$key = '12345678',$iv = '12345678'){
    $len = mb_strlen($data);
    $data = $data.$len."ABCD";
    //不够补0
    $mod = 8-$len%8;
    //return $mod;
    for ($i=0; $i < $mod; $i++) { 
        # code...
        $data.="\0";
    }
   // return $data;
    $data = encrypt($data , $key , $iv);
    return urlencode(base64_encode($data));
}

php版本是7.0的话需要改

//加密  
function encrypt($str , $key , $iv) {  
    return @mcrypt_encrypt(MCRYPT_DES, $key, $str, 'cbc', $iv );  
}  
//解密  
function decrypt($strBin , $key = '12345678',$iv = '12345678'){  
    $strBin = base64_decode(urldecode($strBin));//解密的时候要先urldecode 在base64和加密相反  
  
    return @mcrypt_decrypt( MCRYPT_DES, $key, $strBin, 'cbc', $iv );  
}

之前还遇到一个需求是要int大端字节

a)所有协议数据的明文需要在尾部加上原始数据长度(int大端字节数4字节,协议数据的长度),再加上“ABCD”4个字母,然后按64位进行分组,不足64位的以“\0”补足,分组后的明文采用统一的加密方式生成密文,即采用 “明文+密钥+初始化向量(VI)”。

代码作出相应的更改 

//string to btye[] 
function getBytes($string) {
        $bytes = array();
        for($i = 0; $i < strlen($string); $i++){
             $bytes[] = ord($string[$i]);
        }
        return $bytes;
} 

//int to 大端整型
function integerToBytes($val) {
        $byt = array();
        $byt[0] = ($val >> 24 & 0xff);
        $byt[1] = ($val >> 16 & 0xff);
        $byt[2] = ($val >> 8 & 0xff);
        $byt[3] = ($val & 0xff);
        return $byt;
} 
// byte[] to string
function toStr($bytes) {
        $str = '';
        foreach($bytes as $ch) {
            $str .= chr($ch);
        }
		return $str;
} 

function binToAsc($temp){
	$data = '';
	$len = strlen($temp);
	for($i = 0; i < ($len / 8); $i++){
		$data .= chr(intval(substr($temp, $i * 8 , 8) , 2));
	}
	return $data;
}



function getnbytes($data,$key = '12345678',$iv = '12345678'){
$bytes = getBytes($data);// 内容
$type = integerToBytes(0);// 类型
$len = integerToBytes(count($bytes));//// 内容长度
$orilen = integerToBytes(count($bytes) + 8);////原始长度
$fix = getBytes("ABCD");//固定末尾

$dataLen = count($type) + count($len) + count($bytes) + count($orilen) + count($fix);
$mod = $dataLen % 8;
$padding = "";
if($mod != 0){ //原始数据没有8位对齐
        	$paddingLen = 8 - $mod;
        	$dataLen = $dataLen + $paddingLen;
        	for($i = 0; $i < $paddingLen ; $i++){
        		$padding .= "0";
        	}
        }

$nBytes = array_merge($type , $len , $bytes , $orilen , $fix);
if(!empty($padding)){
	$nBytes = array_merge($nBytes , getBytes($padding));
}
$data = encrypt(toStr($nBytes) , $key , $iv);
return $data;
}


如有不明白的可以到关于我里面联系我