ANSI-X99MAC算法和PBOC的3DES MAC算法,附DES算法工具

ANSI-X99MAC算法和PBOC的3DES MAC算法,附DES算法工具
https://blog.csdn.net/MaxWoods/article/details/48525473

https://blog.csdn.net/redumbrella/article/details/7569887
https://blog.csdn.net/qq445803843/article/details/44927273

/************************************************** 
* PBOC-3DES MAC计算 
**************************************************/  
void PBOC_3DES_MAC( U08 *buf, U32 buf_size, U08 *key, U08 *mac_buf )  
{  
    U08 val[8],xor[8];  
    U08 keyL[8],keyR[8];  
    U08 block[512];  
    U16 x,n;  
    U16 i;  
    memcpy(keyL,key,8);  
    memcpy(keyR,&key[8],8);  
    //准备工作  
    memcpy( block, buf, buf_size ); //将输入数据赋值给临时变量block  
    x = buf_size / 8; //计算有多少个完整的块  
    n = buf_size % 8; //计算最后一个块有几个字节  
    if( n != 0 )     //y非0,则在其后补上0x00...  
    {  
        memset( &block[x*8+n], 0x00, 8-n );  
        block[x*8+n]=0x80;    
    }  
    else  
    {  
        memset( &block[x*8], 0x00, 8 );//如果最后一块长度是8个字节,则最后加80 00。。  
        block[x*8]=0x80;  
    }  
    //开始运算  
    memset( val, 0x00, 8 );//初始向量  
    memcpy( val, UPPAN,8 );  
    DataXOr(val,&block[0], 8,xor);  
    for( i = 1; i < x+1; i++ )    //有多少块循环多少次  
    {   
        CurCalc_DES_Encrypt(keyL,xor,val);//DES加密  
        DataXOr(val,&block[i*8], 8,xor);  
        // j += 8;   //用于取下一块的数据  
    }  
    CurCalc_DES_Encrypt(keyL,xor,val);  
    CurCalc_DES_Decrypt(keyR,val,xor);  
    CurCalc_DES_Encrypt(keyL,xor,val);  
    memcpy(mac_buf,val, 8 );  
}  
  
  

    只要有标准的DES加密和解密算法,类似ANSI-X99MAC算法和PBOC3DES算法就很好实现。他们都是用DES算法再经过一层算法实现的。实现原理看图就能看明白。3DES算法实现就更简单了。就是DES算法再加解密一次。

    /* 
    ************************************************************************************************************** 
    * 
    * 函数原型:void CurCalc_3DES_Encrypt( U08 *inkey, U08 *indata, U08 *outdata ) 
    * 
    * 函数功能:3DES加密 
    * 
    * 函数输入:inkey        16字节密码 
    *           indata      8字节需要加密的数据 
    *                 
    * 函数输出:outdata      8字节加密结果输出 
    * 
    * 函数返回:无 
    *    
    ************************************************************************************************************** 
    */  
    void CurCalc_3DES_Encrypt( U08 *inkey, U08 *indata, U08 *outdata )  
    {  
        U08 LKey[8];  
        U08 RKey[8];  
        U08 TmpDest[8];  
        MyCopy( LKey, inkey,   8 );  
        MyCopy( RKey, inkey+8, 8 );  
        CurCalc_DES_Encrypt( LKey, indata,  outdata );          //加  
        CurCalc_DES_Decrypt( RKey, outdata, TmpDest );          //解  
        CurCalc_DES_Encrypt( LKey, TmpDest, outdata );          //加  
    }  
    /* 
    ************************************************************************************************************** 
    * 
    * 函数原型:void CurCalc_3DES_Decrypt( U08 *inkey, U08 *indata, U08 *outdata ) 
    * 
    * 函数功能:3DES解密 
    * 
    * 函数输入:inkey        8字节密码 
    *           indata      8字节需要解密的数据 
    *                 
    * 函数输出:outdata      8字节解密结果输出 
    * 
    * 函数返回:无 
    *    
    ************************************************************************************************************** 
    */  
    void CurCalc_3DES_Decrypt( U08 *inkey, U08 *indata, U08 *outdata )  
    {  
        U08 LKey[8];  
        U08 RKey[8];  
        U08 TmpDest[8];  
        MyCopy( LKey, inkey,   8 );  
        MyCopy( RKey, inkey+8, 8 );  
        CurCalc_DES_Decrypt( LKey, indata,  outdata );          //解  
        CurCalc_DES_Encrypt( RKey, outdata, TmpDest );          //加  
        CurCalc_DES_Decrypt( LKey, TmpDest, outdata );          //解  
    }  
      
      

      222

      /******************************************************* 
      * 名称:获取报文MAC值 
      * 功能:报文MAC算法 
      * 入口: 
      * *buf ,要计算的数据缓冲区;buf_size,计算数据的长度 
      * *key ,密钥(8B) 
      * 出口:mac_buf,计算出来的MAC值(8B) 
      ansi x9.9 MAC算法 
      ********************************************************/  
      void Ansi99X_Get_MAC( U08 *buf, U32 buf_size, U08 *key, U08 *mac_buf )  
      {  
          U08 val[8],xor[8];  
          U08 block[512];  
          U16 x,n;  
          U16 i,j=0;  
          //准备工作  
          memcpy( block, buf, buf_size ); //将输入数据赋值给临时变量block  
          x = buf_size / 8; //计算有多少个完整的块  
          n = buf_size % 8; //计算最后一个块有几个字节  
          if( n != 0 )     //y非0,则在其后补上0x00...  
          {  
              memset( &block[x*8+n], 0x00, 8-n );  
              x += 1; //将补上的这一块加上去  
          }  
          //开始运算  
          memset( val, 0x00, 8 );  
          for( i = 0; i < x; i++ )  //有多少块循环多少次  
          {  
              DataXOR(val,&block[j], 8,xor);  
              CurCalc_DES_Encrypt(key,xor,val);//DES加密  
              j += 8;  //用于取下一块的数据  
          }  
          memcpy(mac_buf,val, 8 );  
      }  
        
        

        333

        /* 
        ************************************************************************************************* 
        *  异或           
        ************************************************************************************************* 
        */  
        void DataXOR( U08 *source, U08 *dest, U32 size, U08 *out )  
        {  
           int i;  
           for( i = 0; i < size; i++ )  
           { out[i] = dest[i] ^ source[i]; }  
        }  
        
          
          

          实现MAC算法的原理,可以参考CPU卡指令手册或PBOC规范。如图:
          MAC的计算:
          这里写图片描述

          Mac计算步骤:

          1、 终端向CPU卡发送GET CHALLENGE指令,取得4字节随机数,后补“0x00000000”,得到的8字节结果作为MAC计算的初始值。

          2、 检查“04D6960024 + val”的字节数是否为8的倍数,不是则补“0x8000…”,是则补“0x8000000000000000”,然后将得到的结果按8字节每块分成D1、D2、D3…

          3、 判断密钥的长度。

          如果密钥长度为8字节,则按如下方式计算MAC:

          这里写图片描述

          如果密钥长度为16字节,则按如下方式计算MAC:
          这里写图片描述

          MAC简介

          MAC是使用命令的所有元素(包括命令头)产生的。一条命令的完整性,包括命令数据域(如果存在的话)中的数据元,通过安全报文传送得以保证。按照如下的方式使用单重或三重DEA加密方式产生MAC:
          第一步:取8个字节的16进制数字’0’作为初始变量。
          第二步:按照顺序将数据串联在一起形成数据块。
          第三步:将该数据块分成8字节为单位的数据块,标号为D1、D2、D3、D4等。最后的数据块有可能是1-8个字节。

          这里写图片描述
          第四步:如果最后的数据块长度是8字节的话,则在其后加上16进制数字’80 00 00 00 00 00 00 00’,转到第五步。如果最后的数据块长度不足8字节,则在其后加上16进制数字’80’,如果达到8字节长度,则转入第五步;否则在其后加入16进制数字’0’直到长度达到8字节。
          第五步:对这些数据块使用MAC过程密钥进行加密。如果安全报文传送支持单长度的MAC DEA密钥,则依照下图的方式使用MAC 过程密钥来产生MAC。
          第六步:最终得到是从计算结果左侧取得的4字节长度的MAC。
          这里写图片描述

          源码实现:

          void DoSSMac(const BYTE* input, intnInLen, const BYTE* key, int nKeyLen, BYTE* output)  
              {  
                  BYTE byInitVec[8];   //初始向量  
                  BYTE byTemp[8];  
                  memset(byInitVec, 0x00,sizeof(byInitVec));  
                  memset(byTemp,   0x00,sizeof(byTemp));  
                  memcpy(byInitVec, input, 8);  
                  BYTEbySubKey[3][16][48];        //秘钥  
                  memset(bySubKey, 0x01, sizeof(bySubKey));  
                  int i = 0;  
                  int j = (nInLen >> 3);  
            			//构造并生成SubKeys  
                  BYTE nKey = (nKeyLen >> 3) > 3 ?3 : (nKeyLen >> 3);  
                  for (i = 0; i < nKey; i++)  
                  {  
                     SetSubKey(&bySubKey[i], &key[i << 3]);  
                  }  
          		memcpy(output, input, 8);  
                  if (1 == nKey)    //单倍长Key(8字节)  
                  {  
                      j--;  
                      for (int i = 0; i <j; ++i)  
                      {  
                         Xor(input + 8 * (i + 1), output, 8, output);  
                         RunDes(output, 0, &bySubKey[0], output);  
                         //memcpy(byInitVec, output, 8);           //将输出设定为扭转变量  
                      }  
                  }  
                <span style="color:#ff0000;"> //转换关系就在这里  
                 else if (2 == nKey)    //双倍长Key(16字节)  
                  {        
                      j -= 2;  
                      for (i = 0; i < j;++i)  
                      {  
                         Xor(input + 8 * (i + 1), output, 8, output);  
                         RunDes(output, 0, &bySubKey[0],output);       //将输出设定为扭转变量      
                      }  
                      Xor(input + 8 * (++i),output, 8, output);        //最后一块数据和上面加密结果异或  
                      RunDes(output, 0,&bySubKey[0], output);  
                      RunDes(output, 1,&bySubKey[1], output);  
                      RunDes(output, 0,&bySubKey[0], output);  
                  }</span>  
                  else  //三倍长Key(24字节)   尚未验证  
                  {  
                      //j -= 2;  
                      for (i = 0, j =(nInLen >> 3) - 2; i < j; ++i, input += 8)  
                      {  
                         Xor(input + 8 * (i + 1), output, 8, byTemp);  
                         RunDes(byTemp, 0, &bySubKey[0], output);  
                         memcpy(byInitVec, output, 8);           //将输出设定为扭转变量  
                      }  
                      Xor(input + 8 * i,output, 8, output);  
                      RunDes(output, 2,&bySubKey[0], output);  
                      RunDes(output, 1,&bySubKey[1], output);  
                      RunDes(output, 0,&bySubKey[0], output);  
                  }  
              }  
          
          • 0
            点赞
          • 1
            收藏
            觉得还不错? 一键收藏
          • 0
            评论
          根据引用和引用的内容,RSA PBOC工具是一种用于银行卡的密码算法工具,主要用于密钥生成、公私钥加密与解密以及联机交易验证和脱机数据验证等功能。在银行卡的应用中,RSA算法用于脱机数据验证,而PBOC标准则是指中国的银行卡标准,其中包括PBOC1.0和PBOC2.0标准,分别支持使用3DES算法MAC、数据加解密和密钥离散算法。国密算法是用于PBOC3.0标准的增强安全部分的内容。根据引用的描述,该工具在智能卡、USB Key、POS等产品中发挥重要作用,并适用于需要基于命令行测试的嵌入式产品。如果您有更多疑问,可以咨询引用中提供的联系方式。123 #### 引用[.reference_title] - *1* *3* [银行卡安全密码算法辅助计算工具(3DES+RSA)](https://blog.csdn.net/goldboar/article/details/39254663)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *2* [PowerScript--功能强大的智能卡,USB Key, POS脚本命令工具](https://blog.csdn.net/l_z_h/article/details/124048086)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]

          “相关推荐”对你有帮助么?

          • 非常没帮助
          • 没帮助
          • 一般
          • 有帮助
          • 非常有帮助
          提交
          评论
          添加红包

          请填写红包祝福语或标题

          红包个数最小为10个

          红包金额最低5元

          当前余额3.43前往充值 >
          需支付:10.00
          成就一亿技术人!
          领取后你会自动成为博主和红包主的粉丝 规则
          hope_wisdom
          发出的红包
          实付
          使用余额支付
          点击重新获取
          扫码支付
          钱包余额 0

          抵扣说明:

          1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
          2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

          余额充值