<返回更多

JavaScript高手进阶:安全键盘

2022-04-13    修丹道的程序猿
加入收藏

为了安全考虑,很多有登录行为的网站,会对密码输入框进行保护。

本文介绍一种使用安全键盘的输入保护方式,可用于防键盘记录、防止自动点击。

JavaScript高手进阶:安全键盘

 

效果展示

如下图,该输入框带有一个虚拟键盘。

JavaScript高手进阶:安全键盘

 

之所以称其为“安全键盘”,是因为两点:

其一、通过点击虚拟键盘上的按键进行输入,而不需要按下真实键盘上的键位,这样就可以防止很多系统中的后台软件记录按键、窃取密码;

其二、虚拟键盘上的键位,是打乱的,并且是实时随机的,每次页面刷新、每次输入都是不同的键位。如此,可以防止自动化工具或脚本发起的自动点击输入。

功能原理

首先,对指定的输入框,不接受常规按键,而是使用通过虚拟键盘输入。其次,虚拟键盘上的键位,每次都要随机生成。

源码解析

UI部分,在页面使用div、table模拟一个键盘,如下图:

JavaScript高手进阶:安全键盘

 

核心功能是随机键位的产生,在本例中,使用了两种方法随机生成键位,如数字部分,使用sort方法:

JavaScript高手进阶:安全键盘

 

字母部分,使用random方法:

JavaScript高手进阶:安全键盘

 

对于输入内容,是直接给input输入框赋值:

JavaScript高手进阶:安全键盘

 

代码保护

为防止功能逻辑泄露,可对JAVAScript代码进行保护,比如使用JShaman(JS萨满)混淆加密上面的safe_keyword函数代码。

JavaScript高手进阶:安全键盘

 

加密后,代码成为:

JavaScript高手进阶:安全键盘

 

这是加密了一个函数的代码。当然也可以对整体JS代码全部加密,保护效果会更好。

完整源码

以下给出完整源码,包含UI、css风格、JS源码,保存为html即可测试使用。


<html>
    <head>
        <style>
			th,td {
				border: 1px solid #ccc;
				padding: 2px 0;
				text-align: center;
                cursor: pointer
			}
			div {
				border: 1px solid #ccc;
				float: left;
				padding: 1px;
				display: none;
			}
		</style>
    </head>
<body>
    <h3>安全键盘输入</h3>
    <input id="input" readonly="readonly" style="width:475px; height: 80px;"  onclick="hide_or_show();"/>
    <br>
    <div id="keyboard">
        <table cellspacing="1" width="480" onclick="safe_keyword()">
            <tr>
                <td>~</td>
                <td>!</td>
                <td>@</td>
                <td>#</td>
                <td>$</td>
                <td>%</td>
                <td>^</td>
                <td>&</td>
                <td>*</td>
                <td>(</td>
                <td>)</td>
                <td>_</td>
                <td>+</td>
                <td>|</td>
                <td rowspan="2" width="120">退格</td>
            </tr>
            <tr>
                <td>`</td>
                <td class="num">1</td>
                <td class="num">2</td>
                <td class="num">3</td>
                <td class="num">4</td>
                <td class="num">5</td>
                <td class="num">6</td>
                <td class="num">7</td>
                <td class="num">8</td>
                <td class="num">9</td>
                <td class="num">0</td>
                <td>-</td>
                <td>=</td>
                <td></td>
            </tr>
            <tr>
                <td id="safe">q</td>
                <td id="safe">w</td>
                <td id="safe">e</td>
                <td id="safe">r</td>
                <td id="safe">t</td>
                <td id="safe">y</td>
                <td id="safe">u</td>
                <td id="safe">i</td>
                <td id="safe">o</td>
                <td id="safe">p</td>
                <td>{</td>
                <td>}</td>
                <td>[</td>
                <td>]</td>
                <td colspan="2">切换大/小写</td>
            </tr>
            <tr>
                <td id="safe">a</td>
                <td id="safe">s</td>
                <td id="safe">d</td>
                <td id="safe">f</td>
                <td id="safe">g</td>
                <td id="safe">h</td>
                <td id="safe">j</td>
                <td id="safe">k</td>
                <td id="safe">l</td>
                <td>:</td>
                <td>"</td>
                <td>;</td>
                <td>'</td>
                <td colspan="3" rowspan="3">ENTER</td>
            </tr>
            <tr>
                <td id="safe">z</td>
                <td id="safe">x</td>
                <td id="safe">c</td>
                <td id="safe">v</td>
                <td id="safe">b</td>
                <td id="safe">n</td>
                <td id="safe">m</td>
                <td>
                </td>
                <td>></td>
                <td>?</td>
                <td>,</td>
                <td>.</td>
                <td>/</td>
            </tr>
        </table>
    </div>
    <script>
        var htmlCode = {
            "&": "&",
            '"': """,
            "<": "<",
            ">": ">",
        }
        //安全输入
        function safe_keyword() {
            //输入框
            var input = document.getElementById("input");
            var e = window.event || test.caller.arguments[0];
            var el = e.target || e.srcElement;
            if(el.tagName.toLowerCase() == "td" && el.rowSpan <= 1 && el.colSpan <= 1) {
                var str = el.innerHTML;
                str = htmlCode[str] || str;
                input.value += str;
            }
            if(el.innerHTML == "退格") {
                input.value = input.value.slice(0, -1);
            }
            if(el.innerHTML == "切换大/小写") {
                var els = document.getElementsByTagName("td");
                for(var i = 0, l = els.length; i < l; i++) {
                    var str = els[i].innerHTML;
                    if(/^[a-z]$/.test(str)) els[i].innerHTML = str.toUpperCase();
                    if(/^[A-Z]$/.test(str)) els[i].innerHTML = str.toLowerCase();
                }
            }
            //按下回车时隐藏安全键盘
            if(el.innerHTML == "ENTER") {
                hide_or_show();
            }
        }

        //显示或隐藏键盘
        function hide_or_show() {
            var el = document.getElementById("keyboard");
            if(el.offsetWidth > 0) el.style.display = "none";
            else {
                el.style.display = "block";
                random_numbers();
                random_letters();
            }
        }
        
        //随机字母键位
        function random_letters() {
            
            //字符集
            var all_keywords = [];
            for(k=65; k<91; k++){
                all_keywords.push(String.fromCharCode(k).toLowerCase());
            }
            
            //td元素,即各键位
            var els = document.getElementsByTagName("td");
            //遍历td元素
            for(i=0; i<els.length; i++) {
                //键位上显示的内容,即各字母
                var str = els[i].innerHTML;

                //随机字母
                var rnd_key = parseInt( all_keywords.length * Math.random() );
                
                if(els[i].id == "safe"){
                    els[i].innerHTML = all_keywords[rnd_key];
                    
                    //使用后删除
                    delete all_keywords[rnd_key];
                    all_keywords.splice(rnd_key,1);
                }
            }
            
        }

        //随机数字键位
        function random_numbers() {

            //随机排序数字
            var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].sort(function() {
                return Math.random() > 0.5 ? 1 : -1;
            });
            
            //取得所有键位
            var els = document.getElementsByTagName("td");
            for(var i = 0, j = 0, l = els.length; i < l; i++) {

                //键位上的字符
                var str = els[i].innerHTML;
                //用正则表达式判断是不是数字键位,并赋新的随机值
                if(/^d$/.test(str)) els[i].innerHTML = arr[j++];
            }
        }
    </script>
</body>
</html>
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>