Home Web Front-end H5 Tutorial Using spring+html5 to achieve secure transmission of random numeric password keyboard

Using spring+html5 to achieve secure transmission of random numeric password keyboard

Feb 09, 2017 pm 03:39 PM
secure transmission

随着互联网的飞跃式发展,移动支付已越来越受欢迎并且已成为常态,很多三方支付公司推出了很多支付方式如快捷支付、认证支付、

扫码支付等等。快捷支付和认证支付可分为移动app控件和移动HTML5网页。用户第一次使用快捷支付或认证支付进行支付的时候,需先绑定

银行卡。在绑定银行卡的过程中,需要验证银行卡信息。不同银行、不同银行卡验证的要素不一样,有些需要验证四要素,有的需要验证八要

素。对于需要验证银行卡的交易密码的情况,怎样保证交易密码的安全不被别人所窃取呢?为了保证交易密码不在传输过程中被窃取,出现了

安全传输随机数字密码键盘。

安全传输随机数字密码键盘怎么实现呢?今天给大家详细的介绍安全传输随机数字密码键盘的原理和代码实现。下图是实现的数字键

盘效果:

Using spring+html5 to achieve secure transmission of random numeric password keyboard

一、实现原理

用户点击“交易密码”输入框,页面异步向后台发送“获取密码键盘”的请求,后台接收到请求之后随机生成“1234567890与随机密文的对应

关系”和“随机密文”和“1234567890图片“的对应关系,然后把它们关系放入dto实例中并放入Redis中,最后把随机密文以集合的方式返回到页面,

页面js获取到密文集合后以循环的方式向后台请求对应的数字图片流,并展示在页面。

当用户点击数字键盘中的数字图片,就会把图片对应的密文放入到pkey隐藏输入框中,多个数字以逗号隔开,当点击支付的时候,就会

把peykey隐藏输入框的值传入到后台,后台从redis中取出“密文”与“1234567890数字“的对应关系,就取出了对应交易密码。

二、具体实现

1).Html5页面

页面主要展示密码输入框和支付按钮,需要导入jQuery、bootstrap及pwdkey.js等。下面是具体代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

<%@ 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=&#39;<c:url value="/js/bootstrap/css/bootstrap.min.css"/>&#39;>

<!-- 引入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="/static/imghw/default1.png"  data-src="<c:url value="  class="lazy"  /images/phone.png"/ alt="Using spring+html5 to achieve secure transmission of random numeric password keyboard" >" />

        <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>

Copy after login

2).密码键盘js代码


用户点击“交易密码”输入框,页面异步向后台发送“获取密码键盘”的请求,后台接收到请求之后把随机密文以集合的方式返回到页面,

页面js获取到密文集合后以循环的方式向后台请求对应的数字图片流并展示在页面。具体代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

$(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) {

    $(&#39;.keyboard&#39;).addClass("navbar-fixed-bottom");

    $(&#39;.keyboard&#39;).css({

        "z-index" : "9999"

    });

    if (rangdom == null || rangdom == "") {

        alert("无法加载密码键盘,请刷新后重试!");

        return false;

    }

    if ($("#pkey").val() == null || $("#pkey").val() == "undefined") {

        $(obj)

                .html(

                        $(obj).html()

                                + &#39;<input type="hidden" name="pkey" id="pkey" />&#39;);

    }

    $("#pin").html("交易密码");

    setCssNomal();

    $("#pkey").val("");

    $

            .ajax({

                type : &#39;post&#39;,

                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 = &#39;<tr>&#39;;

                        for (var i = 0; i < 12; i++) {

                            if ((i + 1) % 3 == 0 && i != 0 && i <= 5) {

                                content = content

                                        + &#39;<td style="width:33%;"  key="&#39;

                                        + data[i]

                                        + &#39;" ontouchstart="return ontouch(this);"><img src="&#39;

                                        + path

                                        + &#39;/common/getKey.do?key=&#39;

                                        + data[i]

                                        + &#39;&rangdom=&#39;

                                        + rangdom

                                        + &#39;" style="height:20px;" id="key_img"/></td></tr><tr>&#39;;

                            } else if (i <= 7) {

                                content = content

                                        + &#39;<td style="width:33%;" key="&#39;

                                        + data[i]

                                        + &#39;" ontouchstart="return ontouch(this);"><img src="&#39;

                                        + path

                                        + &#39;/common/getKey.do?key=&#39;

                                        + data[i]

                                        + &#39;&rangdom=&#39;

                                        + rangdom

                                        + &#39;" style="height:20px;" id="key_img"/></td>&#39;;

                            } else if (i == 8) {

                                content = content

                                        + &#39;<td style="width:33%;"  ontouchstart="return deleteOne();"><img src="&#39;

                                        + path

                                        + &#39;/images/keys/delete.png" style="height:20px;"  id="key_img"/></td>&#39;

                                        + &#39;</tr><tr>&#39;;

                            } else if (i < 11) {

                                content = content

                                        + &#39;<td style="width:33%;" key="&#39;

                                        + data[i - 1]

                                        + &#39;" ontouchstart="return ontouch(this);"><img src="&#39;

                                        + path

                                        + &#39;/common/getKey.do?key=&#39;

                                        + data[i - 1]

                                        + &#39;&rangdom=&#39;

                                        + rangdom

                                        + &#39;" style="height:20px;" id="key_img"/></td>&#39;;

                            } else {

                                content = content

                                        + &#39;<td style="width:33%;" onclick="return _ok();"><img src="&#39;

                                        + path

                                        + &#39;/images/keys/ok.png" style="height:20px;" id="key_img"/></td>&#39;

                                        + &#39;</tr>&#39;;

                            }

 

                        }

                        key_table.html(content);

 

                        setTimeout(function() {

                            $("#keyboard").show();

                        }, 600);

                        hengshuping();

                    }

 

                },

                error : function() {

                    alert("无法加载键盘,请刷新后重试!");

                }

            });

}

function ontouch(obj) {

    var pkey = $("#pkey").val();

    var key = $(obj).attr("key");

    if (pkey == "") {

        $("#pin").html("");

    }

    var content = $("#pin").html();

    if (content != "" && content.length >= 6) {

        return false;

    }

    if (pkey != "") {

        key = "," + key;

    }

    pkey = pkey + key;

    $("#pkey").val(pkey);

    $("#pin").append("*");

    setCssKey();

 

}

function deleteOne() {

    var pkey = $("#pkey").val() + "";

    if (pkey == "") {

        return false;

    }

    var local = pkey.lastIndexOf(",");

    if (local == -1) {

 

        $("#pkey").val("");

        $("#pin").html("交易密码");

        setCssNomal();

    } else {

        pkey = pkey.substring(0, local - 1);

        var content = $("#pin").html();

        content = content.substring(0, content.length - 1);

        $("#pkey").val(pkey);

        $("#pin").html(content);

    }

 

}

function _ok() {

    $("#key_table").html("");

    $("#keyboard").hide();

}

function showkey() {

    $("#keyboard").show();

}

function hideKey() {

    $("#key_table").html("");

    $("#keyboard").hide();

}

function setCssKey() {

    $("#pin").css({

        "font-size" : "18px",

        "color" : "#030303",

        "font-weight" : "normal",

        "letter-spacing" : "1px"

    });

}

function setCssNomal() {

    $("#pin").css({

        "font-size" : "16px",

        "color" : "#D2D1D1",

        "font-weight" : "normal"

    });

}

Copy after login

3).获取密码键盘后台方法


该方法将随机生成“1234567890与随机密文的对应关系”和“随机密文”和“1234567890图片“的对应关系,然后把它们关系放入dto实例中

并放入redis中,最后把随机密文以集合的方式返回到页面。具体代码如下:


获取密码键盘:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

/**

     *

     * @Description: 获取密码键盘

     * @param request

     * @param rangdom 随机字符串

     * @return

     *

     */

    @SuppressWarnings("unchecked")

    @ResponseBody

    @RequestMapping(value = "common/pkey.do", method = RequestMethod.POST)

    public Object digitkeyboard(HttpServletRequest request, String rangdom) {

        LOG.info("[获取密码键盘digitkeyboard][parames:outOrderId=" + rangdom + "]");

        try {

            if (StringUtils.isBlank(rangdom)) {

                return "";

            }

            PwdKeyDto pwdkey = PwdKeyUtils.digitkeyboard();

            redisUtil.set("pwdkey_" + rangdom, pwdkey,

                    redisUtil.getDigitkeyimeOut());

            return pwdkey.getRundomKeys();

        } catch (Exception e) {

            LOG.error("[获取密码键盘digitkeyboard][error:{}",e);

        }

        return "";

    }

密码PwdKeyDto:

    /**

 *

 * @ClassName: PwdKeyDto

 * @Description: 密码映射Dto

 * @author xxxx <a target="_blank" href="mailto:xxxx@xxx.com">xxxx@xxx.com</a>

 * @date 2015年6月25日 上午11:01:20

 *

 */

public class PwdKeyDto implements Serializable{

    /**

        描述*/

    private static final long serialVersionUID = 1L;

    private List<String> rundomKeys;// 随机Keys

    private Map<String, String> valueKeyMaps;// 密文和明文映射

    private Map<String, String> imgKeyMaps;// 密文和明文映射

 

    public PwdKeyDto() {

        super();

        // TODO Auto-generated constructor stub

    }

 

    public List<String> getRundomKeys() {

        return rundomKeys;

    }

 

    public void setRundomKeys(List<String> rundomKeys) {

        this.rundomKeys = rundomKeys;

    }

 

    public PwdKeyDto(List<String> rundomKeys, Map<String, String> valueKeyMaps,

            Map<String, String> imgKeyMaps) {

        super();

        this.rundomKeys = rundomKeys;

        this.valueKeyMaps = valueKeyMaps;

        this.imgKeyMaps = imgKeyMaps;

    }

 

    public Map<String, String> getValueKeyMaps() {

        return valueKeyMaps;

    }

 

    public void setValueKeyMaps(Map<String, String> valueKeyMaps) {

        this.valueKeyMaps = valueKeyMaps;

    }

 

    public Map<String, String> getImgKeyMaps() {

        return imgKeyMaps;

    }

 

    public void setImgKeyMaps(Map<String, String> imgKeyMaps) {

        this.imgKeyMaps = imgKeyMaps;

    }

 

}

Copy after login

生成键盘的PwdKeyUtils工具类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

/**

 

 * @ClassName: PwdKeyUtils

 * @Description: 密码处理工具类

 * @author xxxx <a target="_blank" href="mailto:xxxx@xxxx.com">xxxx@xxxx.com</a>

 * @date 2015年6月25日 上午11:03:24

 

 */ 

public class PwdKeyUtils { 

    private final static Map<String, String> imagesValueMap; 

   

    /**

     

     * @Description: 获取密码键盘映射关系

     * @param imagesValueMap

     * @return

     

     */ 

    static

        imagesValueMap = new HashMap<String, String>(); 

        imagesValueMap.put("0"

                "images/keys/0.png"); 

        imagesValueMap.put("1"

                "images/keys/1.png"); 

        imagesValueMap.put("2"

                "images/keys/2.png"); 

        imagesValueMap.put("3"

                "images/keys/3.png"); 

        imagesValueMap.put("4"

                "images/keys/4.png"); 

        imagesValueMap.put("5"

                "images/keys/5.png"); 

        imagesValueMap.put("6"

                "images/keys/6.png"); 

        imagesValueMap.put("7"

                "images/keys/7.png"); 

        imagesValueMap.put("8"

                "images/keys/8.png"); 

        imagesValueMap.put("9"

                "images/keys/9.png"); 

    

   

    public static PwdKeyDto digitkeyboard() { 

        List<String> rundomKeys = new ArrayList<String>();// 随机key映射 

        Map<String, String> valueKeys = new HashMap<String, String>();// 密文和明文映射 

        Map<String, String> imgKeyMaps = new HashMap<String, String>();// 密文和图片映射 

        List<String> keys = new ArrayList<String>(); 

        for (int i = 0; i < 10; i++) { 

            keys.add(i + ""); 

        

        for (int i = 0; i < 10; i++) { 

            Random r = new Random(); 

            int index = r.nextInt(keys.size()); 

            String key = keys.get(index); 

            keys.remove(index); 

            String randomkey = randomKey(24); 

            rundomKeys.add(randomkey); 

            valueKeys.put(randomkey, key); 

            imgKeyMaps.put(randomkey, imagesValueMap.get(key)); 

        

        PwdKeyDto dto = new PwdKeyDto(rundomKeys, valueKeys, imgKeyMaps); 

        return dto; 

    

   

    /**

     

     * @Description:获取动态key

     * @param num

     *            key位数

     * @return

     

     */ 

    public static String randomKey(int num) { 

        StringBuffer sb = new StringBuffer(""); 

        char[] chars = { &#39;0&#39;, &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;A&#39;, 

                &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39;, &#39;I&#39;, &#39;J&#39;, &#39;K&#39;, &#39;L&#39;, &#39;M&#39;, 

                &#39;N&#39;, &#39;O&#39;, &#39;P&#39;, &#39;Q&#39;, &#39;R&#39;, &#39;S&#39;, &#39;T&#39;, &#39;U&#39;, &#39;V&#39;, &#39;W&#39;, &#39;X&#39;, &#39;Y&#39;, 

                &#39;Z&#39;, &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;, &#39;g&#39;, &#39;h&#39;, &#39;i&#39;, &#39;j&#39;, &#39;k&#39;, 

                &#39;l&#39;, &#39;m&#39;, &#39;n&#39;, &#39;o&#39;, &#39;p&#39;, &#39;q&#39;, &#39;r&#39;, &#39;s&#39;, &#39;t&#39;, &#39;u&#39;, &#39;v&#39;, &#39;w&#39;, 

                &#39;x&#39;, &#39;y&#39;, &#39;z&#39; }; 

        for (int i = 0; i < num; i++) { 

            int id = (int) Math.ceil(Math.random() * 60); 

            sb.append(chars[id]); 

        

        return sb.toString(); 

    

   

    /**

     

     * @Description:解密pin

     * @param request

     * @param pin

     * @return

     

     */ 

    public static String decryptPinData(HttpServletRequest request, 

            String ciphertextpin) throws Exception { 

        if (StringUtils.isNotBlank(ciphertextpin)) { 

            Map<String, String> valuekeys = (Map<String, String>) request 

                    .getSession().getAttribute("valuekeys"); 

            if (valuekeys == null || valuekeys.size() != 10) { 

                throw new Exception(); 

            

            String[] ciphertextpins = ciphertextpin.split(","); 

            StringBuffer sb = new StringBuffer(""); 

            for (String ctpin : ciphertextpins) { 

                sb.append(valuekeys.get(ctpin)); 

            

        

        return null; 

    

}

Copy after login

4).获取图片流后台方法

用户页面获取到随机密文集合后以循环的方式向后台请求该方法获取对应的数字图片流。具体代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

/**

     * 获取key图片

     *

     * @throws Exception

     */

    @RequestMapping(value = "/common/getKey.do", method = RequestMethod.GET)

    public void getKey(String key, String rangdom, HttpServletRequest request,

            HttpServletResponse response) throws Exception {

        LOG.info("[获取密码键盘key(getKey)][parms:key=" + key + "]");

        PwdKeyDto pwdkey = (PwdKeyDto) redisUtil.get("pwdkey_" + rangdom);

        if (pwdkey == null || pwdkey.getImgKeyMaps() == null) {

            LOG.error("获取图片[getKey]:未获取到对应的键盘的映射关系");

            throw new Exception();

        }

        Map<String, String> imagekeys = pwdkey.getImgKeyMaps();

        String path = imagekeys.get(key);

        String rootPath = request.getSession().getServletContext()

                .getRealPath("/");

        path = rootPath + path;

        LOG.info("[获取密码键盘key(getKey)][path=" + path + "]");

        if (StringUtils.isNotEmpty(path)) {

            try {

                InputStream fis = new FileInputStream(new File(path));

                BufferedInputStream bis = new BufferedInputStream(fis);

                OutputStream fos = response.getOutputStream();

                BufferedOutputStream bos = new BufferedOutputStream(fos);

                String fileName = "image.";

                String[] strs = path.split("\\.");

                fileName = fileName + strs[strs.length - 1];

                setFileDownloadHeader(request, response, fileName);

                int byteRead = 0;

                byte[] buffer = new byte[8192];

                while ((byteRead = bis.read(buffer, 0, 8192)) != -1) {

                    bos.write(buffer, 0, byteRead);

                }

                bos.flush();

                fis.close();

                bis.close();

                fos.close();

                bos.close();

 

            } catch (Exception e) {

                LOG.error("获取图片[path:" + path + "])失败:" + e.toString(), e);

            }

        }

    }

Copy after login

5).用户支付

当用户点击数字键盘中的数字图片,就会把图片对应的密文放入到pkey隐藏输入框中,多个数字以逗号隔开,当点击支付的时候,就

会把peykey隐藏输入框的值传入到后台,后台从redis中取出“密文”与“1234567890数字“的对应关系,就取出了对应交易密码。具体代码如下:

页面提交支付js:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

function check()

{

    hideKey();

    var pin="";

     

         

        pin=$("#pkey").val();

        if(pin==""||pin==undefined)

        {

            bool=false;

            alert("请输入交易密码");

             

            return false;

        }else

        {

            var keys=pin.split(",");

            if(keys.length!=6)

            {

                alert("请输入6位交易密码");

                 

                return false;

            }

        }

        $.ajax({

            type : &#39;post&#39;,

            url : "test/pay.do",

            data : {

                random:"2321321321",

                pin:pin

            },

            cache : false,

            success : function(data) {

                if(data.success)

                    {

                      alert(data.message);

                    }else{

                         

                    }

                 

            },

            error : function(){

                 

                alert("系统异常,请重试!");

            }

        });

}

Copy after login

后台解析密文方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

/**

     *

     * @Description: 支付

     * @param pin 交易密码密文

     * @param random 随机码

     * @return

     *

     */

    @ResponseBody

    @RequestMapping(value = "/test/pay.do", method = RequestMethod.POST)

    public Object pay(String pin,String random, HttpServletRequest request) {

        try {

            LOG.info("[支付(pay)][params:pin=" + pin + ",random="+random+"]");

            if (StringUtils.isNotBlank(pin)) {

                StringBuffer sb = new StringBuffer("");

                PwdKeyDto pwdkey = (PwdKeyDto) redisUtil.get("pwdkey_" + random);

                if (pwdkey == null || pwdkey.getValueKeyMaps() == null) {

                    return new Result(false,"密码键盘已失效,请重新输入密码");

                }

                Map<String, String> valuekeys = pwdkey.getValueKeyMaps();

                String[] pins = pin.split(",");

                if (pins.length != 6) {

                    return new Result(false,"交易密码位数不对");

                }

                for (String pinKey : pins) {

                    String val = valuekeys.get(pinKey);

                    if (StringUtils.isBlank(val)) {

                        return new Result(false,"密码键盘已失效,请重新输入密码");

                    }

                    sb.append(val);

                }

                /**

                 * sb.toString()就是明文交易密码,下面就是具体的支付操作

                 */

                 

            }

            return new Result(true, "成功");

         

        } catch (Exception e) {

            LOG.error("[支付(pay)][error:{}]",e);

            return new Result(false, "支付异常,请重试!");

        }

 

    }

Copy after login


以上就是 使用spring+html5实现安全传输随机数字密码键盘的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Three secrets for deploying large models in the cloud Three secrets for deploying large models in the cloud Apr 24, 2024 pm 03:00 PM

Compilation|Produced by Xingxuan|51CTO Technology Stack (WeChat ID: blog51cto) In the past two years, I have been more involved in generative AI projects using large language models (LLMs) rather than traditional systems. I'm starting to miss serverless cloud computing. Their applications range from enhancing conversational AI to providing complex analytics solutions for various industries, and many other capabilities. Many enterprises deploy these models on cloud platforms because public cloud providers already provide a ready-made ecosystem and it is the path of least resistance. However, it doesn't come cheap. The cloud also offers other benefits such as scalability, efficiency and advanced computing capabilities (GPUs available on demand). There are some little-known aspects of deploying LLM on public cloud platforms

How to use Vue for data encryption and secure transmission How to use Vue for data encryption and secure transmission Aug 02, 2023 pm 02:58 PM

How to use Vue for data encryption and secure transmission Introduction: With the development of the Internet, data security has received more and more attention. In web application development, data encryption and secure transmission are important means to protect user privacy and sensitive information. As a popular JavaScript framework, Vue provides a wealth of tools and plug-ins that can help us achieve data encryption and secure transmission. This article will introduce how to use Vue for data encryption and secure transmission, and provide code examples for reference. 1. Data encryption and data encryption

PHP 401 response: Resolve Unauthorized errors and enhance security PHP 401 response: Resolve Unauthorized errors and enhance security Apr 09, 2024 pm 03:15 PM

In web development, a 401 Unauthorized error means that the client is not authorized to access a specific resource. PHP provides multiple processing methods: 1. Use 401 HTTP status code; 2. Output JSON response; 3. Redirect to the login page. To enhance security, you can take the following measures: 1. Use HTTPS; 2. Enable CSRF protection; 3. Implement input validation; 4. Use an authorization framework.

MySQL and Oracle: Comparison of support for data encryption and secure transmission MySQL and Oracle: Comparison of support for data encryption and secure transmission Jul 12, 2023 am 10:29 AM

MySQL and Oracle: Comparison of support for data encryption and secure transmission Introduction: Data security has become increasingly important in today's information age. From personal privacy to business secrets, maintaining the confidentiality and integrity of data is critical for any organization. Among database management systems (DBMS), MySQL and Oracle are the two most popular options. In this article, we will compare the extent to which MySQL and Oracle support data encryption and secure transmission, and provide some code examples.

Azure JWT validation in Go not working Azure JWT validation in Go not working Feb 09, 2024 am 11:12 AM

I have a gohttp server. I want to secure my routes using azurejwt token. I am able to generate the token but cannot verify it. This is what I do: packagemainimport("context""errors""fmt""github.com/dgrijalva/jwt-go""github.com/lestrrat-go/jwx/jwa""github.com/lestrrat-go/ jwx/jwk"njwt"github.com

How to use TLS 1.2 with MySql Go driver? How to use TLS 1.2 with MySql Go driver? Feb 10, 2024 am 09:40 AM

We have to use tls1.2 to connect to our mysql server. In our java application we use the following jdbcurl-jdbc:mysql://xxxx-001-dev.cluster-xx-2.rds.amazonaws.com/bats?**enabledtlsprotocols=tlsv1.2** in our When connecting to mysql in my go application, I cannot achieve a similar configuration - cfg1:=mysql.config{user:"adm

How to securely transfer files via ssh using scp command under Linux How to securely transfer files via ssh using scp command under Linux Feb 09, 2024 pm 01:39 PM

On Unix or Linux operating systems, the scp utility (securecopy) is similar to the better-known command cp, but is used to transfer files and directories between hosts over a secure, encrypted network. Since it relies on ssh for data transfer, it provides the same security and uses the same authentication as ssh. Unlike rcp, the scp command will prompt you for a password for authentication if required. In this article, we will delve into secure file transfer in Linux and learn how to use the scp command. With detailed explanations and example use cases of common scp switches and options, you'll learn how to use this utility. It's important to know the following before you start since scp relies on s

Password-free ssh settings for mac? Password-free ssh settings for mac? Feb 16, 2024 am 08:36 AM

Preface: This article is here to introduce you to the relevant content about password-free ssh settings on Mac. I hope it will be helpful to you, let’s take a look. Teach you step by step how to configure SSH multiple accounts on Mac 1. View the public key through cat~/.ssh/id_rsa.pub, copy the entire public key, and configure it to a backend such as GitHub. First, search for, download and install the Termius software in the AppStore. After the installation is complete, open the application and enter the main page, click the [NewHost] button in the lower right corner. 3. Configure iterm2 on Mac to remember the multi-site ssh account password. First, you need to install iterm2 yourself. After opening the iterm2 official website, click Download

See all articles