只允许特定电脑访问网站(根据访问者硬件信息区分)
最近接到一个需求,需求放想要实现只允许特定人员的电脑登录公司里的后台管理系统。刚接到这个需求觉得是异想天开,受限于B/S架构想要通过浏览器来识别不同电脑从来没听说过。正常第一反映是通过ip地址来进行限制,但是这个后台管理系统在互联网上运行,而需求方想要实现的是全国各地分公司下面的部分特定人员的办工电脑才能登录后台(且不说各分公司上网的路由外网ip会变,位于同一个局域网的办工环境下不同用户访问互联网时出口ip都是一样的,根本不能用ip来区分)!
当时直接回复这个浏览器不好实现,如果想要实现可以考虑开发客户端程序来实现。但是需求方不依不饶说他们找人评估过了可以用控件等方式实现!好家伙这都行,很早之前做一个身份证阅读器接口时接触过activex控件这个东西,当时是在ie上安装身份证阅读器厂家提供的插件后可以实现在网页获取身份证阅读器读到的身份证信息,这个玩意儿这次不提还真想不起来。于是乎又去网上调研了一番,结论是ie浏览器可以调用原生的AcitveX可以获取一些硬件信息,利用这些硬件信息可以实现电脑身份的鉴别。废话不多说,下面分享下理论方案:
一、利用IE控件获取硬件信息(有条件的可以自行开发activex插件)
大家可以网上查下具体怎么实现ie的控件获取硬件信息的,一般来说至少需要获取mac地址来进行身份识别,但是mac地址太容易伪造。也可以考虑使用cpu及硬盘序列号来作为识别依据。
经过测试win10下的 ie浏览器经过设置是可以通过网页js获取mac地址的
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <object classid="CLSID:76A64158-CB41-11D1-8B02-00600806D9B6" id="locator" style="display:none;visibility:hidden"></object> <object classid="CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223" id="foo" style="display:none;visibility:hidden"></object> <form name="myForm"> <br/>MAC: <input type="text" name="macAddress"> <br/>IP: <input type="text" name="ipAddress"> <br/>HOST: <input type="text" name="hostName"> </form> <script> function networkInfo(){ var wmi = new ActiveXObject ("WbemScripting.SWbemLocator"); var service = wmi.ConnectServer("."); e = new Enumerator(service.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")); for(; !e.atEnd(); e.moveNext()) { var s = e.item(); var macAddress = unescape(s.MACAddress); } return macAddress; } alert(networkInfo()); </script> <script language="javascript"> var sMacAddr=""; var sIPAddr=""; var sDNSName=""; var service = locator.ConnectServer(); service.Security_.ImpersonationLevel=3; service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration'); </script> <script FOR="foo" EVENT="OnObjectReady(objObject,objAsyncContext)" LANGUAGE="JScript"> if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true){ if(objObject.IPEnabled && objObject.IPAddress(0) !=null && objObject.IPAddress(0) != "undefined") sIPAddr = objObject.IPAddress(0); if(objObject.MACAddress != null &&objObject.MACAddress != "undefined") sMacAddr = objObject.MACAddress; if(objObject.DNSHostName != null &&objObject.DNSHostName != "undefined") sDNSName = objObject.DNSHostName; } </script> <script FOR="foo" EVENT="OnCompleted(hResult,pErrorObject, pAsyncContext)" LANGUAGE="JScript"> myForm.macAddress.value=sMacAddr; myForm.ipAddress.value=sIPAddr; myForm.hostName.value=sDNSName; </script> </body> </html>
访问会提示加载,如果选择允许后面也是没有任何反应的,这里需要直接在ie的Inetnet选项里面去设置才行。
获取硬件信息后有什么用?
正常情况下每台电脑的硬件信息都不一样,如果我们想要实现限制/允许特定电脑能购访问web系统,那么只需要用户在访问网站的时候先用js获取特征信息,请求后台查看该信息是否添加在白/黑明单中,然后再决定是否允许登录。
这种方案的风险: 如果其他无授权的电脑想要登录,那么他得知道允许登录的电脑信息是什么才行,如果他能接触到可以正常登录系统的电脑,那么他可以通过修改其他电脑的mac地址或者直接劫持并篡改js文件来绕过校验。另外如果该系统登录信息是通过cookies来验证的话,也可以获取cookies后在专门搭建的cookies会话保持平台实现永久可登录(前提是账号允许多地登录且cookies没设置过期时间)
二、利用加密狗实现
这个方案没有实际验证,停留在理论阶段。 加密狗的种类有很多,可以开发一个软件加密狗,这个加密狗的作用就是启动后会在本地端口开启一个web服务(假设是127.0.0.1:5770),web系统在js代码中会去访问调用127.0.0.1:5770,加密狗返回一串加密内容,然后在登录时拿着加密内容以及账户信息去web系统后端服务器验证。服务揭秘内容后如果是正确的且账号密码正确则允许登录!这个实现方法的关键在于加密规则以及何时需要校验加密狗(如果只在登录的时候校验一次加密狗可能无法保证后续的操作也是在同一台电脑上)
加密狗的关键逻辑: 1、可以选择限定加密狗只能在指定电脑上运行防止把加密狗插到别的电脑,在加密狗第一运行的时候要读取电脑的cpu、硬盘、主板序列号并使用算法生成一个注册序列号, 再设计一个注册码算法,只有用户填入的注册码跟注册码算法计算的结果一样程序才会运行 2、加密狗启动后的服务,需要一个可逆加密算法。建议是根据(注册码+当前时间戳+固定长度的复杂字符串+固定长度的随机数)作为可变文本,然后通过双方约定的对称/非对称加密算法进行加密。 2.1、在客户机访问调用127.0.0.1:5770的时候返回加密的内容。后台服务器收到客户机发过来的恶加密内容时进行解密,如果解密出来的注册码确实存在(防止有人破解程序后使用注册机生成的注册码)则提供下一步的服务。 3、这种方式安全性相对比较高,除非有人能破解加密狗程序并获得加密密钥及生成算法。
三、建立vpn通道利用ip鉴别
这个方案安全性也不高,而且就实现成本来说不如第一种方便。可以将所有需要用这个系统的电脑接入vpn,然后利用一台vpn网络中的服务器进行反向代理,这样就能购确保按ip来区分访问用户从而实现指定电脑可访问系统(这种方式太容易被人冒用vpn账号/ip了);这种时候可以再用浏览器头信息进行限制,只有ip及ip对应的浏览器头信息匹配才允许登录。
四、安装特定ssl证书
先说明下这个方案没有实际操作过也没有经过充分的理论调研。记得早之前的12306必须要下载安装12306的证书才可以正常使用某些网站服务,可以参考它来实现客户机的身份鉴别,区别在于我们的证书只能安装在特定的电脑上,而且最好是让运维给安装,不要把证书文件发给用户自己安装!一旦证书被泄露就失去意义了。
后记
如果真的是比较重要的系统,在采取上面或别的措施后,必须要完善日志功能,每次用户访问的时候记录下ip、时间、浏览器指纹信息等内容,通过数据分析去发现异常的登录用户。比如说1天內一个用户换了3、4个不同版本的浏览器来访问系统,那大概率是有问题的。
基于互联网精神,在注明出处的前提下本站文章可自由转载!
本文链接:https://ranjuan.cn/web-access-limit/
微信赞赏支付宝赞赏
发表评论