随着互联网的飞跃式发展,移动支付已越来越受欢迎并且已成为常态,很多三方支付公司推出了很多支付方式如快捷支付、认证支付、扫码支付等等。快捷支付和认证支付可分为移动app控件和移动HTML5网页。用户第一次使用快捷支付或认证支付进行支付的时候,需先绑定银行卡。在绑定银行卡的过程中,需要验证银行卡信息。不同银行、不同银行卡验证的要素不一样,有些需要验证四要素,有的需要验证八要素。对于需要验证银行卡的交易密码的情况,怎样保证交易密码的安全不被别人所窃取呢?为了保证交易密码不在传输过程中被窃取,出现了安全传输随机数字密码键盘。
安全传输随机数字密码键盘怎么实现呢?今天给大家详细的介绍安全传输随机数字密码键盘的原理和代码实现。下图是实现的数
字键盘效果:

一、实现原理
用户点击“交易密码”输入框,页面异步向后台发送“获取密码键盘”的请求,后台接收到请求之后随机生成“1234567890与随机密文的对应关系”和“随机密文”和“1234567890图片“的对应关系,然后把它们关系放入dto实例中并放入redis中,最后把随机密文以集合的方式返回到页面,页面js获取到密文集合后以循环的方式向后台请求对应的数字图片流,并展示在页面。
当用户点击数字键盘中的数字图片,就会把图片对应的密文放入到pkey隐藏输入框中,多个数字以逗号隔开,当点击支付的时候,就会把peykey隐藏输入框的值传入到后台,后台从redis中取出“密文”与“1234567890数字“的对应关系,就取出了对应交易密码。
二、具体实现
1).HTML5页面
页面主要展示密码输入框和支付按钮,需要导入JQuery、bootstrap及pwdkey.js等。下面是具体代码:
<%@ page language="java" import="java.util.*"
contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
<head>
<meta name="viewport"
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<meta http-equiv="Cache-Control" CONTENT="private,must-revalidate">
<link rel="stylesheet"
href='<c:url value="/js/bootstrap/css/bootstrap.min.css"/>'>
<!-- 引入js脚本文件 begin -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="<c:url value="/js/JQuery/jquery-1.10.0.min.js"/>"></script>
<script src="<c:url value="/js/bootstrap/js/bootstrap.min.js"/>"></script>
<script type="text/javascript" src="<c:url value="/js/pwdkey.js"/>"></script>
<title>xxx付款</title>
<style type="text/css">
.input-out {
padding-top: 20px;
}
.btn-out {
margin:30px 10px;
}
.btn-out button {
width: 100%;
background: #5CACEE;
border: #5CACEE;
color: #fff;
height: 50px;
border-radius: 3px;
font-size: 18px;
font-family: "Microsoft Yahei", "??????", SimHei, Tahoma, Arial, Helvetica, STHeiti;
}
.keyboard {
background: #fff;
}
.keyboard table {
width:100%;
text-align:center;
}
.keyboard table td {
padding: 15px;
}
.keyboard table a,
.keyboard table a:hover,
.keyboard table a:focus {
color: #333;
text-decoration: none;
}
.input-out label {
color:#D2D1D1;
font-weight: normal;
font-size: 16px;
}
.bottom {
color:#888888;
margin-bottom: 15px;
text-align:center;
margin-top:100px;
}
.bottom a {
color:#888888;
}
.bottom img {
vertical-align: middle;
width: 18px;
}
</style>
</head>
<body>
<form action="<%=path%>/pay" method="post" id="from">
<div class="content">
<div class="input-out pass-label" style="border-bottom: 1px solid #ddd;padding-left: 12px;" random="2321321321" path="<%=path%>" >
<label id="pin" >交易密码</label>
</div>
</div>
<div class="btn-out">
<button type="button" class="btn btn-default" ontouchstart="check();" id="pay">支付</button>
</div>
</form>
<div class="bottom" id="bottom-out">
<img src="<c:url value="/images/phone.png"/>" />
<span>客服电话:4000-xxx-xxx</span>
</div>
<!-- jianpan-->
<div class="keyboard" style="display:none;" id="keyboard">
<table class="table-bordered" id="key_table">
</table>
</div>
</body>
</html>
</div>
2).密码键盘js代码
用户点击“交易密码”输入框,页面异步向后台发送“获取密码键盘”的请求,后台接收到请求之后把随机密文以集合的方式返回到页面,页面js获取到密文集合后以循环的方式向后台请求对应的数字图片流并展示在页面。具体代码如下:
$(document).ready(
function() {
$("#pay").removeAttr("disabled");
$("input").click(function() {
hideKey();
});
$("button").click(function() {
hideKey();
});
$(".pass-label").click(function() {
var rangdom = $(this).attr("random");
var path = $(this).attr("path");
pwdkey(this, rangdom, path);
});
window.addEventListener(
"onorientationchange" in window ? "orientationchange"
: "resize", hengshuping, false);
});
function hengshuping() {
if (window.orientation == 180 || window.orientation == 0) {
$("div#keyboard td").each(function() {
$(this).css("padding", "15px");
});
}
if (window.orientation == 90 || window.orientation == -90) {
$("div#keyboard td").each(function() {
$(this).css("padding", "8px");
});
}
window.scrollTo(0, $(".pass-label").offset().top);
}
function pwdkey(obj, rangdom, path) {
$('.keyboard').addClass("navbar-fixed-bottom");
$('.keyboard').css({
"z-index" : "9999"
});
if (rangdom == null || rangdom == "") {
alert("无法加载密码键盘,请刷新后重试!");
return false;
}
if ($("#pkey").val() == null || $("#pkey").val() == "undefined") {
$(obj)
.html(
$(obj).html()
+ '<input type="hidden" name="pkey" id="pkey" />');
}
$("#pin").html("交易密码");
setCssNomal();
$("#pkey").val("");
$
.ajax({
type : 'post',
url : path + "/common/pkey.do",
cache : false,
async : false,
data : {
rangdom : rangdom
},
success : function(data) {
if (data == null || data == "" || data == "undefined"
|| data.length != 10) {
alert("无法加载密码键盘,请刷新后重试!");
return false;
} else {
var key_table = $("#key_table");
key_table.html("");
var content = '<tr>';
for (var i = 0; i < 12; i++) {
if ((i + 1) % 3 == 0 && i != 0 && i <= 5) {
content = content
+ '<td style="width:33%;" key="'
+ data[i]
+ '" ontouchstart="return ontouch(this);"><img src="'
+ path
+ '/common/getKey.do?key='
+ data[i]
+ '&rangdom='
+ rangdom
+ '" style="height:20px;" id="key_img"/></td></tr><tr>';
} else if (i <= 7) {
content = content
+ '<td style="width:33%;" key="'
+ data[i]
+ '" ontouchstart="return ontouch(this);"><img src="'
+ path
+ '/common/getKey.do?key='
+ data[i]
+ '&rangdom='
+ rangdom
+ '" style="height:20px;" id="key_img"

