MAC校验
这两天在改写一段java MAC校验代码为php类型的,之前也没接触过php,所以说中间出现了好多问题,这里保存一下代码:
首先用到的工具包:
<?php function strToHex($string) { $string = mb_convert_encoding($string, 'ASCII','UTF-8'); $hex = ""; for ($i = 0; $i < strlen($string); $i++) $hex .= dechex(ord($string[$i])); $hex = strtoupper($hex); return $hex; } function hexToStr($hex) { $string = ""; for ($i = 0; $i < strlen($hex) - 1; $i += 2) $string .= chr(hexdec($hex[$i] . $hex[$i +1])); return $string; } function SingleDecToHex($dec) { $tmp = ""; $dec = $dec % 16; if ($dec < 10) return $tmp . $dec; $arr = array ( "A", "B", "C", "D", "E", "F" ); return $tmp . $arr[$dec -10]; } function SingleHexToDec($hex) { $v = ord($hex); if (47 < $v & $v < 58) return $v -48; if (96 < $v & $v < 103) return $v -87; } function SetToHexString($str) { if (!$str) return false; $tmp = ""; for ($i = 0; $i < strlen($str); $i++) { $ord = ord($str[$i]); $tmp .= SingleDecToHex(($ord - $ord % 16) / 16); $tmp .= SingleDecToHex($ord % 16); } return $tmp; } function UnsetFromHexString($str) { if (!$str) return false; $tmp = ""; for ($i = 0; $i < strlen($str); $i += 2) { $tmp .= chr(SingleHexToDec(substr($str, $i, 1)) * 16 + SingleHexToDec(substr($str, $i +1, 1))); } return $tmp; }
des ECB模式的加解密代码:
mac校验代码:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <?php include ('DES.php'); include ('Util.php'); class MAC919desUtil{ function MAC($mackey,$data,$key){ $des = new Crypt_DES(); $des->setKey(hexToStr('3535353535353535')); $primaryKey =SetToHexString($des->decrypt(hexToStr($key)));//主密钥的明文 $des->setKey(hexToStr($primaryKey)); $mingkey = SetToHexString($des->decrypt(hexToStr($mackey))); //用主密钥的明文解密mackey得到mackey的明文 $data =strToHex($data);//将数据转换成16进制 //组后一组不足16补0 $de=""; $datas=$this->retData($data);// 将macdata 分数值,每组16位(8 byte()) for($i=0;$i<count($datas);$i++){ if($i==0){ //第一次只做DES加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de=SetToHexString($des->encrypt(hexToStr($datas[$i]))); }else{ //用上一次 DES加密结果对第 i 组数据做异或 $de=$this->myXOR($de,$datas[$i]); // 对异或后的数据做DES加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de=SetToHexString($des->encrypt(hexToStr($de))); } } // des 加密最终结果用mackey后16位解密 $des->setKey(hexToStr(substr($mingkey,16))); $de =SetToHexString($des->decrypt(hexToStr($de))); // 解密后 再用mackey前16位加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de = SetToHexString($des->encrypt(hexToStr($de))); return $de; } function retData($data){ $len=0; if(strlen($data)%16==0){ $len=strlen($data)/16; }else{ $len=(strlen($data)/16)+1; } $datas=Array(); for ($i = 0; $i <$len; $i++) { if (strlen($data)>= 16) { $datas[$i] = substr($data,0,16); $data = substr($data,16); } else { $datas[$i] = $this->moveRigZero($data, 16, "0"); break; } } return $datas; } // 右补 0 function moveRigZero($args,$len,$str) { if (strlen($args)<$len) { while (strlen($args)<$len) { $args.=$str; } } return $args; } /* * 数据异或 */ function myXOR($str1,$str2) { $hex = ""; if (strlen($str1)!= strlen($str2)) { echo "异或数据长度不等"; } for ($i = 0; $i < strlen($str1); $i++) { $hex.=SingleDecToHex(intval(substr($str1,$i,1),16)^(intval(substr($str2,$i,1),16))); } return strtoupper($hex); } } ?>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <?php include ('DES.php'); include ('Util.php'); class MAC919desUtil{ function MAC($mackey,$data,$key){ $des = new Crypt_DES(); $des->setKey(hexToStr('3535353535353535')); $primaryKey =SetToHexString($des->decrypt(hexToStr($key)));//主密钥的明文 $des->setKey(hexToStr($primaryKey)); $mingkey = SetToHexString($des->decrypt(hexToStr($mackey))); //用主密钥的明文解密mackey得到mackey的明文 $data =strToHex($data);//将数据转换成16进制 //组后一组不足16补0 $de=""; $datas=$this->retData($data);// 将macdata 分数值,每组16位(8 byte()) for($i=0;$i<count($datas);$i++){ if($i==0){ //第一次只做DES加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de=SetToHexString($des->encrypt(hexToStr($datas[$i]))); }else{ //用上一次 DES加密结果对第 i 组数据做异或 $de=$this->myXOR($de,$datas[$i]); // 对异或后的数据做DES加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de=SetToHexString($des->encrypt(hexToStr($de))); } } // des 加密最终结果用mackey后16位解密 $des->setKey(hexToStr(substr($mingkey,16))); $de =SetToHexString($des->decrypt(hexToStr($de))); // 解密后 再用mackey前16位加密 $des->setKey(hexToStr(substr($mingkey,0,16))); $de = SetToHexString($des->encrypt(hexToStr($de))); return $de; } function retData($data){ $len=0; if(strlen($data)%16==0){ $len=strlen($data)/16; }else{ $len=(strlen($data)/16)+1; } $datas=Array(); for ($i = 0; $i <$len; $i++) { if (strlen($data)>= 16) { $datas[$i] = substr($data,0,16); $data = substr($data,16); } else { $datas[$i] = $this->moveRigZero($data, 16, "0"); break; } } return $datas; } // 右补 0 function moveRigZero($args,$len,$str) { if (strlen($args)<$len) { while (strlen($args)<$len) { $args.=$str; } } return $args; } /* * 数据异或 */ function myXOR($str1,$str2) { $hex = ""; if (strlen($str1)!= strlen($str2)) { echo "异或数据长度不等"; } for ($i = 0; $i < strlen($str1); $i++) { $hex.=SingleDecToHex(intval(substr($str1,$i,1),16)^(intval(substr($str2,$i,1),16))); } return strtoupper($hex); } } ?>
好多问题,这里保存一下我的代码留着以后用