【iPro案例分享】iPro实现加密机的负载
  

江威 Lv1发表于 2017-7-3 16:55



iPro实现加密机的负载



背景介绍
       数据加密机主要用于实现对主机应用层数据加/解密、消息来源正确性验证、密钥管理等。全国大多数商业银行,城市一卡通系统、公交卡系统、社保卡系统、加油卡系统,金融IC卡系统、电子联行系统、综合业务系统、信用卡系统、银证转帐系统、企业银行系统、网上证券交易系统都有应用.

       在1996年以前,国产的数据加密机尚未产生,国内银行均采用国外的加密产品,主要是英国的RACAL(雷卡)和加拿大的ATALLA品牌。这两个公司有着较长的从事金融信息安全的研究和为金融业提供信息安全产品的历史,其产品可适应金融信息安全的各种要求,方便地和各种计算机硬件平台和软件平台接口,技术比较成熟。为彻底解决我国金融交易的安全问题,并同时做到和国外金融业务接轨。1996年国家信息安全主管部门指定两家最具实力的科研机构(总参56所和电子部30所)进行研究开发,这两家单位在同年先后推出了各自的金融数据加密机(总参56所的SJL06型,电子部30所的SJL05型),两种机型都属于信源加密设备,并均通过了国家密码管理委员会的鉴定.

     目前在社保领域用到的国内加密机主要有成都卫士通信息安全技术有限公司的SJL05型, 广州江南科友科技股份有限公司的SJL06型,北京江南歌盟科技有限公司的SJL22型。
     由于加解密对资源的使用率较高,在银行等金融领域中衍生出了负载的需求,以缓解不断增加的业务量对加解密的需求。


协议分析
45212595a0a2025993.png
加密机数据包采用“数据包长度(2字节)+用户保留位(8字节)+数据载荷”的方式进行传输。
如上图所示,这个数据包长度为1041字节,去掉长度标记占用的2字节,有效载荷为1039字节,即"040f"所表示的长度

解决方案
对加密机的负载,需要将客户端的IP信息透传给加密机,这里主要利用8字节的用户保留字段,在进行请求转发时将客户端的IP和端口插入到8字节保留位的前6个字节,应答转发时将其再还原成原始数据。
  1. <font size="3" face="微软雅黑">TCP.enable_mblb()
  2. local function split (s, p)
  3.     local rt= {}
  4.     string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
  5.     return rt
  6. end


  7. event CLIENT_ACCEPT {
  8.     client_ip = TCP.remoteaddr()
  9.     client_port = TCP.remoteport()
  10.     --LOG.log(LOG.INFO, "ip:port |"..tostring(client_ip)..":"..tostring(client_port))
  11.     local port = tonumber(client_port)  
  12.     local ip = split(client_ip, '.') --把xxx.yyy.zzz.qqq形式的ip,把.去掉,节省空间
  13.     client_info = struct.pack(">bbbbH", ip[1],ip[2], ip[3], ip[4],port) --源IP源端口,组装成大端序二进制,一共6个字节
  14.     TCP.collect()
  15. }
  16. local flag = nil
  17. event CLIENT_DATA {
  18.     while TCP.offset() >= 2 do
  19.     local data_len = struct.unpack(">H", TCP.payload(2))
  20.     if TCP.offset() >= data_len + 2 then  --收齐了数据
  21.         if TCP.offset() >= 8 then
  22.             flag = string.sub(TCP.payload(), 3, 8)  --记录请求方向收到的原始数据头部,应答时需要修改回去
  23.             TCP.replace(3, 9, client_info)  --后两个字节不用处理
  24.         else  --异常处理,虽然按协议收完了包,但是不能完成替换
  25.               if LOG.ratelimit(LOG.LOW) then
  26.                   LOG.log(LOG.DEBUG, "data error!")
  27.                   TCP.close()
  28.                   break
  29.              end
  30.         end
  31.         local rs = pool("pool-default-bank")
  32.         if not rs then
  33.             rs = pool("pool-backup-bank")
  34.         end
  35.         if not rs then
  36.             LOG.log(LOG.DEBUG, "pool failed")
  37.             TCP.close()
  38.             break
  39.        end
  40.        TCP.release(data_len + 2)
  41.        TCP.notify(TCP.request)
  42.    else
  43.        break
  44.     end
  45.         end
  46.         TCP.collect()
  47. }

  48. event SERVER_CONNECTED{
  49.     TCP.collect()
  50. }

  51. event SERVER_DATA {
  52.      while TCP.offset() >= 2 do
  53.          local d_len = struct.unpack(">H", TCP.payload(2))
  54.          if TCP.offset() >= d_len + 2 then
  55.              if TCP.offset() >= 8 then
  56.                    if not flag then
  57.                           LOG.log(LOG.DEBUG, "flag is nil")
  58.                           TCP.close()
  59.                           break
  60.                    end
  61.                    TCP.replace(3, 9, flag) --把源ip及源端口替换回请求方向收到的部分
  62.                    TCP.release(d_len + 2)
  63.                    TCP.notify(TCP.response)
  64.                    TCP.detach()
  65.              else  --异常处理,虽然按协议收完了包,但是不能完成替换
  66.                    if LOG.ratelimit(LOG.LOW) then
  67.                          LOG.log(LOG.DEBUG, "data error!")
  68.                          TCP.close()
  69.                          break
  70.                    end
  71.              end
  72.         else
  73.              break
  74.         end
  75.      end
  76.      TCP.collect()
  77. }
  78. </font>
复制代码

更多iPro知识与案例分享,请点击

喜欢这篇分享吗?喜欢就给楼主打点赏吧!点个赞也是极大的鼓励!

发帖可获得5S豆;若您的分享被加精或推荐优秀等,将获得更多S豆奖励,了解更多S豆奖励信息

完善手机号和公司名称,让服务更省心更便捷!立即完善

XiaoYang Lv6发表于 2017-7-4 14:22
  
学习了!