zoukankan      html  css  js  c++  java
  • 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);
        }
        
        
    
    }
    
    
    ?>

    好多问题,这里保存一下我的代码留着以后用

  • 相关阅读:
    C++如何在Dialog和View中显示梯度背景颜色
    C++MFC的关键类(View,Application,Frame,Document等等)之间访问方法列表
    C++深入分析MFC文档视图结构(项目实践)
    C++如何修改SDI程序的默认背景颜色
    BAPI使用HR_INFOTYPE_OPERATION函数批量导入HR信息纪录代码样例(0759信息类型)
    C++在单文档的应用程序增加多个视图
    SD定价过程的16个字段的作用说明
    HR上载信息类型的长文本的样例代码
    C++在工具条中加入组合框控件
    C++如何锁定splitter窗口
  • 原文地址:https://www.cnblogs.com/zhangkaijia/p/2987375.html
Copyright © 2011-2022 走看看