UKey证书认证单点登录实战使用-利用activeX控件

1.什么是ukey

UKey是一种通过USB (通用串行总线接口)直接与计算机相连、具有密码验证功能、可靠高速的小型存储设备。(图片和本段取至百度百科)
在这里插入图片描述

2.Ukey的认证流程

1.请求认证服务器拿到随机数

在这里插入图片描述

2.响应认证客户端

在这里插入图片描述
通过xml格式的数据,请求websocket,使用浏览器activeX控件调出认证客户端
部分代码:

 var addr = "ws://127.0.0.1:30318";

 var bodyx = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
      "<getsignandtokenreq version=\"1\">" +
      "<challenge>" + random + "</challenge>" +
      "</getsignandtokenreq> "
 // 建立websocket连接
 var msWs = new WebSocket(addr)
  msWs.onmessage = function (ev) {
	 // 在这里面去处理
  }

3.认证客户端输入口令进行票据认证

在这里插入图片描述
输入口令后,这步我们就不用管了,会自动的去去验证是否正确,如果输入错误,返回的xml结构里面大概如下

<xxx>
	<result>0</result>
	....
</xxx>

可以通过这个<result>节点去判断是否认证成功

4.认证成功后解密获取认证信息

每个ukey制造商的加密方式都不一样,请阅读制造商提供的文档,下面讲解我用的这个key的加密方式

在这里插入图片描述

要经过两次解密,再对最后一次解密获取<dncode>节点进行字符串截取,可以获取到认证信息,再拿数据库进行对比,再在服务端写一个无密登录即可实现ukey单点登录

解密示例代码

function getUkeyByXml(xml) {
    console.log("开始解析xml======")
    try {
      // 初始化xml解析对象
      var xmlObj = new DOMParser();
      var xmlDom = xmlObj.parseFromString(xml, "text/xml");
      var tokenInfo = xmlDom.getElementsByTagName("tokeninfo")
      var s1_code = tokenInfo[0].textContent
      // 对第一层数据进行base64转码
      var tokenInfoXml = atob(s1_code);
      addLog("tokenInfoXml", tokenInfoXml)
      var om1 = tokenInfoXml.indexOf("<ticketinfo>");
      var om2 = tokenInfoXml.indexOf("</ticketinfo>");
      tokenInfoXml = tokenInfoXml.substring(om1, om2) + "</ticketinfo>";
      var tokenDom = xmlObj.parseFromString(tokenInfoXml, "text/xml")
      var ticketinfo = tokenDom.getElementsByTagName("ticketinfo");
      var s2_code = ticketinfo[0].textContent;
      // 对第二层数进行base64转码
      var userInfoXml = atob(s2_code);
      addLog("userInfoXml", userInfoXml)
      var userDom = xmlObj.parseFromString(userInfoXml, "text/xml");
      var userInfo = userDom.getElementsByTagName("dncode");
      addLog("userInfo", userInfo)
      var userContent = userInfo[0].textContent
      addLog("userContent", userContent)
      var ukeyCodeIndex = userContent.indexOf("Identifier=");
      var ukeyCode = userContent.substring(ukeyCodeIndex, ukeyCodeIndex + 38 + ("Identifier".length))
      addLog("ukeyCode", ukeyCode)
      ukeyCode = ukeyCode.replace("Identifier=", "").trim()
      console.log("ukeyCode = [" + ukeyCode + "]")
      addLog("ukeyCode", ukeyCode)
      console.log("解析完成 =========")
      return ukeyCode;
    } catch (error) {
      console.log("解析失败")
      return null;
    }
  }
    function addLog(log1, log2) {
    $("#login_res").text($("#login_res").text() + "[info] --" + new Date().toLocaleString() + " -- " + log1 + "|" + log2 + "\n")
  }

注意,每一家的ukey制造商的解密和流程都不一样,本文仅供要做ukey的小白逻辑参考,不懂的可以私聊哦~

发布了240 篇原创文章 · 获赞 66 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/u014131617/article/details/103870973