首页 >后端开发 >php教程 >有没有谁搞过银联POS终端mac算法[php版本]?

有没有谁搞过银联POS终端mac算法[php版本]?

WBOY
WBOY原创
2016-06-06 20:37:001212浏览

安全机制

对报文进行MAC,以实现防篡改

发起方先对标签数据进行Base64编码,根据编码后的数据,然后进行循环异或(将数据分成若干个8个字节的数据段,最后不足8位后加0x00补齐8位)。得到标签数据。然后将新的报文发送给对方。

为原始报文的Base64编码结果

<code>xml</code><code><?xml version="1.0" encoding="UTF-8"?>
<request>
    <header>
        <sender>ccb_pos</sender>
        <servicename>pos_service</servicename>
        <time>20111121094051</time>
    </header>
    
    <originaldata>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48ZGF0YT48cHJvZHVjdD4wMzI2PC9wcm9kdWN0PjxwcmVtaXVtPjExMDAuMDwvcHJlbWl1bT48ZHJpdmVycz48ZHJpdmVyPkphbWVzPC9kcml2ZXI+PGRyaXZlcj5UZWRkeTwvZHJpdmVyPjwvZHJpdmVycz48L2RhdGE+</originaldata>
    <mac> 8U42KXyd76FSCmRT</mac>   //char 16
    
</request>
</code>

处理方式

接收方在接收到报文后,将标签数据分成若干个8个字节的数据段,最后不足8位后加0x00补齐8位,循环异或一次。然后和标签数据进行比对。如果比对一致表示通过验证,最后将标签数据按照Base64解码,得到交易明文数据。

参考文档

http://blog.163.com/gene_lu/blog/static/6402542120133151112717/

网上找了一段PHP代码

这代码有问题,大概方式。

<code>php</code><code><?php /** 防止乱码 */
header("Content-type:text/html;charset=utf-8");


//MCRYPT 密码配置
$MCRYPT_key = "key:232"; //密钥
$MCRYPT_cipher = MCRYPT_DES; //密码类型
$MCRYPT_modes = MCRYPT_MODE_ECB; //密码模式


function MCRYPT_str($str,$type=1){
global $MCRYPT_key,$MCRYPT_cipher,$MCRYPT_modes;

$iv = mcrypt_create_iv(mcrypt_get_iv_size($MCRYPT_cipher,$MCRYPT_modes),MCRYPT_RAND);//初始化向量

if($type==1){
$str = mcrypt_encrypt($MCRYPT_cipher,$MCRYPT_key,$str,$MCRYPT_modes,$iv); //加密函数
}else{
    $str = mcrypt_decrypt($MCRYPT_cipher,$MCRYPT_key,$str,$MCRYPT_modes,$iv); 
}
return $str;
}

    $str="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48ZGF0YT48cHJvZHVjdD4wMzI2PC9wcm9kdWN0PjxwcmVtaXVtPjExMDAuMDwvcHJlbWl1bT48ZHJpdmVycz48ZHJpdmVyPkphbWVzPC9kcml2ZXI+PGRyaXZlcj5UZWRkeTwvZHJpdmVyPjwvZHJpdmVycz48L2RhdGE+";

    var_dump($str);
    echo '<br/><br><br>';

    var_dump(base64_decode($str));
    echo '<br><br><br>';

    var_dump(mac_($str));
    echo '<br><br><br>';


//说明:MAC算法,将字符串$data分为八字节为单位的数据块,标号为D1,D2,D3..,如果最后的数据块不足
//8字节,则在后面加上\x00直到长度达到8字节为止,最后按照下面流程产生MAC,
//8字节的初始值:\x00\x00\x00\x00\x00\x00\x00\x00
//流程:初始值 异或 D1 —>异或的结果进行des  异或  D2 —>异或的结果进行des  异或  D2 —>异或的结果进行des
function mac_($data)
{

  //设初始值
  $init="\x00\x00\x00\x00\x00\x00\x00\x00";
  //对$data进行8字节分割,获得数组
  $tmp_data=strtoarray($data,8);
  
  $tmp_init=$init;
  foreach($tmp_data as $value)
  {

    //进行异或运算
    $tmp_init=myEncrypt($tmp_init,$value);

var_dump($tmp_init);
    //进行加密
    //$tmp_init=MCRYPT_str($tmp_init);
 
  }
  
  var_dump($tmp_init);
  return bin2hex($tmp_init);
}

//函数名:strtoarray
//说明:将字符串按8字节切割,最后不足8字节的用\x00填补
function strtoarray($str,$limit)
{
  $len=strlen($str);
  $tmp_arr=array();
  $count=floor($len/$limit);
  $left_num=$len-$count*$limit;
  for($i=0;$i$limit+1)
   {
    $str=substr($str,$limit,strlen($str));
   }
  }
  return $tmp_arr;
}

//函数名:myEncrypt
//说明:异或运算函数
function myEncrypt($string, $key)
{
   for($i=0;$i<strlen for return>
</strlen></code>

不知道哪位研究过没有,怎么做的,没有头绪。

回复内容:

安全机制

对报文进行MAC,以实现防篡改

发起方先对标签数据进行Base64编码,根据编码后的数据,然后进行循环异或(将数据分成若干个8个字节的数据段,最后不足8位后加0x00补齐8位)。得到标签数据。然后将新的报文发送给对方。

为原始报文的Base64编码结果

<code>xml</code><code><?xml version="1.0" encoding="UTF-8"?>
<request>
    <header>
        <sender>ccb_pos</sender>
        <servicename>pos_service</servicename>
        <time>20111121094051</time>
    </header>
    
    <originaldata>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48ZGF0YT48cHJvZHVjdD4wMzI2PC9wcm9kdWN0PjxwcmVtaXVtPjExMDAuMDwvcHJlbWl1bT48ZHJpdmVycz48ZHJpdmVyPkphbWVzPC9kcml2ZXI+PGRyaXZlcj5UZWRkeTwvZHJpdmVyPjwvZHJpdmVycz48L2RhdGE+</originaldata>
    <mac> 8U42KXyd76FSCmRT</mac>   //char 16
    
</request>
</code>

处理方式

接收方在接收到报文后,将标签数据分成若干个8个字节的数据段,最后不足8位后加0x00补齐8位,循环异或一次。然后和标签数据进行比对。如果比对一致表示通过验证,最后将标签数据按照Base64解码,得到交易明文数据。

参考文档

http://blog.163.com/gene_lu/blog/static/6402542120133151112717/

网上找了一段PHP代码

这代码有问题,大概方式。

<code>php</code><code><?php /** 防止乱码 */
header("Content-type:text/html;charset=utf-8");


//MCRYPT 密码配置
$MCRYPT_key = "key:232"; //密钥
$MCRYPT_cipher = MCRYPT_DES; //密码类型
$MCRYPT_modes = MCRYPT_MODE_ECB; //密码模式


function MCRYPT_str($str,$type=1){
global $MCRYPT_key,$MCRYPT_cipher,$MCRYPT_modes;

$iv = mcrypt_create_iv(mcrypt_get_iv_size($MCRYPT_cipher,$MCRYPT_modes),MCRYPT_RAND);//初始化向量

if($type==1){
$str = mcrypt_encrypt($MCRYPT_cipher,$MCRYPT_key,$str,$MCRYPT_modes,$iv); //加密函数
}else{
    $str = mcrypt_decrypt($MCRYPT_cipher,$MCRYPT_key,$str,$MCRYPT_modes,$iv); 
}
return $str;
}

    $str="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48ZGF0YT48cHJvZHVjdD4wMzI2PC9wcm9kdWN0PjxwcmVtaXVtPjExMDAuMDwvcHJlbWl1bT48ZHJpdmVycz48ZHJpdmVyPkphbWVzPC9kcml2ZXI+PGRyaXZlcj5UZWRkeTwvZHJpdmVyPjwvZHJpdmVycz48L2RhdGE+";

    var_dump($str);
    echo '<br/><br><br>';

    var_dump(base64_decode($str));
    echo '<br><br><br>';

    var_dump(mac_($str));
    echo '<br><br><br>';


//说明:MAC算法,将字符串$data分为八字节为单位的数据块,标号为D1,D2,D3..,如果最后的数据块不足
//8字节,则在后面加上\x00直到长度达到8字节为止,最后按照下面流程产生MAC,
//8字节的初始值:\x00\x00\x00\x00\x00\x00\x00\x00
//流程:初始值 异或 D1 —>异或的结果进行des  异或  D2 —>异或的结果进行des  异或  D2 —>异或的结果进行des
function mac_($data)
{

  //设初始值
  $init="\x00\x00\x00\x00\x00\x00\x00\x00";
  //对$data进行8字节分割,获得数组
  $tmp_data=strtoarray($data,8);
  
  $tmp_init=$init;
  foreach($tmp_data as $value)
  {

    //进行异或运算
    $tmp_init=myEncrypt($tmp_init,$value);

var_dump($tmp_init);
    //进行加密
    //$tmp_init=MCRYPT_str($tmp_init);
 
  }
  
  var_dump($tmp_init);
  return bin2hex($tmp_init);
}

//函数名:strtoarray
//说明:将字符串按8字节切割,最后不足8字节的用\x00填补
function strtoarray($str,$limit)
{
  $len=strlen($str);
  $tmp_arr=array();
  $count=floor($len/$limit);
  $left_num=$len-$count*$limit;
  for($i=0;$i$limit+1)
   {
    $str=substr($str,$limit,strlen($str));
   }
  }
  return $tmp_arr;
}

//函数名:myEncrypt
//说明:异或运算函数
function myEncrypt($string, $key)
{
   for($i=0;$i<strlen for return>
</strlen></code>

不知道哪位研究过没有,怎么做的,没有头绪。

全是二进制的, php 弄, 太费劲了吧. 为何不用 java 来搞

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn