EAP 认证 五元组转换三元组算法实现

最近工作中接触到部分网络通信编程,需要将鉴权五元组转换成三元组,故将此涉及的算法记录一下,方便以后回顾。

USIM卡用2G终端,HLR会发送五元组鉴权,同时VLR会启动五元组/三元组转换流程,将五元组变换为三元组,登陆2G网络。

同时,SIM卡用3G终端,HLR会发送三元组鉴权,同时VLR会启动三元组/五元组转换流程,将三元组变换为五元组,登陆3G网络。

背景知识:

【2G/3G鉴权参数的转换】

2G/3G交互操作中的关键是在两个系统中密钥的长度不同。3G鉴权后,有128位密码和完整性密钥CK和IK。在2G鉴权完成后,只有64位密钥Kc服务于网络,故需要一种转换功能,转换3G密钥的长度以符合2G的长度。

 

当USIM卡接入2G网络时,USIM卡需要支持转换函数,能将XRES’转为SRES’,将CK和IK转为Kc;同时,在不共核心网的情况下,3G HLR/AuC能支持五元组到三元组的转换,从而可以向手机注册的2G MSC/VLR或者SGSN返回三元组认证向量;或者,在共核心网的情况下,HLR/Auc不进行五元组到三元组的转换,而由MSC/VLR与SGSN进行CK+IK到Kc的转换,以支持2G无线网络。

当SIM卡接入3G网络时,其认证过程和2G系统基本相同,只是3G核心网的VLR/SGSN需要通过标准的转换函数将Kc转换为CK和IK,以支持3G无线网络;同时,3G终端从SIM卡得到Kc后,也需要通过同样的转换函数将Kc转换为CK和IK,这样后续终端和3G基站间可以进行加密和完整性保护。

其中 CK+IK到Kc 转换执行c3算法,Xres 到Sres 转换 执行c2算法,以上算法分别通过java 和 pythod 代码实现。


def c2( xres ):
    l = len(xres)
    if l > 16:
        raise PacketError( "xres length:%d error" % l )
    elif l < 16:
        xres += "\x00" * ( 16 - l )
    item = [ xres[pos:pos+4] for pos in range(0, len(xres), 4) ]
    res = item[0]
    for pos in range( 1, len(item) ):
        res = Xor(res, item[pos])
    return res

def c3( ck, ik ):
    if len(ck) != 16:
        raise PacketError( "ck length:%d error" % len(ck) )
    if len(ik) != 16:
        raise PacketError( "ik length:%d error" % len(ik) )
    item = [ ck[0:8], ck[8:16], ik[0:8], ik[8:16] ]
    res = item[0]
    for pos in range( 1, len(item) ):
        res = Xor(res, item[pos])
    return res

  private String c3(String ck, String ik) {
    if (ck.length() != 32) {
      log.error("ck length error" + ck.length());
    }
    if (ik.length() != 32) {
      log.error("ik length error" + ik.length());
    }
    List<String> item = new ArrayList<>();
    item.add(ck.substring(0, 16));
    item.add(ck.substring(16, 32));
    item.add(ik.substring(0, 16));
    item.add(ik.substring(16, 32));
    return getResult(item);
  }

  private String c2(String xres) {
    int len = xres.length();
    if (len > 32) {
      log.error("X_RES length error..." + len);
    }
    if (len < 32) {
      StringBuilder sb = new StringBuilder(xres);
      for (int i = 0; i < 32 - len; i += 2) {
        sb.append("00");
      }
      xres = sb.toString();
    }
    String regex = "(.{8})";
    String data = xres.replaceAll(regex, "$1,");
    List<String> item = Arrays.asList(data.split(","));
    return getResult(item);
  }

  private String getResult(List<String> item) {
    String res = item.get(0);
    for (int i = 1; i < item.size(); i++) {
      res = xor(res, item.get(i));
    }
    return res;
  }

  private String xor(String data1, String data2) {
    byte[] res = BufferUtilities.hexStringToByteArray(data1);
    byte[] data = BufferUtilities.hexStringToByteArray(data2);
    byte[] result = new byte[res.length];
    for (int i = 0; i < res.length; i++) {
      result[i] = (byte) (res[i] ^ data[i]);
    }
    return BufferUtilities.byteToHexString(result, 0, result.length);
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值