使用RSA非对称加密算法对密码进行加密,能够保证传输数据的安全性。RSA公钥和私钥在服务器端生成,并且把私钥保存到服务器,把公钥的模数和指数传递给前端。前端根据模数和指数对密码进行加密,将密码密文传递给服务器。服务器根据私钥对密文进行解密,最后完成登录验证。本文主要介绍:“前端登录页面HTML代码”、“前端请求后端,获取RSA公钥的模数和指数”、“后端生成RSA公钥的模数和指数”、“将公钥的模数和指数返回给前端”、“前端根据公钥的模数和指数对密码进行加密”、“前端将手机号和密码密文传递给后端”、“后端使用私钥对密码密文进行解密”、“后端验证账号密码是否正确,完成登录验证”。

1、前端登录页面HTML代码。

<div id="loginMain"><div id="loginPic"><img src="../../images/login.png" alt=""></div><div id="loginInfomation" class="layui-form"><p><img src="../../images/name.png" alt=""></p><h4 style="line-height:50px;">欢迎登录博销宝管理后台</h4><h4 style="font-size:15px; line-height:16px; margin-bottom: 15px;">v1.0.0</h4><div class="layui-form-item"><label class="layui-form-label"><strongclass="requiredField">*</strong>公司编号:</label><div class="layui-input-block"><input type="text" class="layui-input"name="${staffField.FIELD_NAME_companySN}" lay-verify="companySN"placeholder="请输入公司编号" maxlength="8" /></div></div><div class="layui-form-item"><label class="layui-form-label"><strongclass="requiredField">*</strong>手机号码:</label><div class="layui-input-block"><input type="text" class="layui-input"name="${staffField.FIELD_NAME_phone}" lay-verify="phone"maxlength="11" placeholder="请输入手机号码" /></div></div><div class="layui-form-item"><label class="layui-form-label"><strongclass="requiredField">*</strong>密码:</label><div class="layui-input-block"><input type="password" class="layui-input"name="${staffField.FIELD_NAME_pwdEncrypted}" lay-verify="password"maxlength="16" placeholder="请输入密码" /></div></div><p><button class="layui-btn layui-btn-lg layui-btn-normal" lay-submitlay-filter="login">登录</button></p><p><img src="../../images/logoName.png" alt=""></p><input type="hidden" id="CURRENT_ReleaseNbrVersionNO" value="2.0.0" /><br></div></div>

2、前端请求后端,获取RSA公钥的模数和指数。

将手机号作为参数传递给后端:

//登录系统form.on("submit(login)", function(data){var loading = layer.load(1);var loginInfo = data.field;var password = loginInfo.pwdEncrypted;$.ajax({url: staffGetToken_url,type: method_post,dataType: "JSON",data: {"phone": loginInfo.phone},cache: false,async: true,success : function(data){var modulus = data.rsa.modulus;var exponent = data.rsa.exponent;var rsa = new RSAKey();rsa.setPublic(modulus, exponent);var res = rsa.encrypt(password);if(res){loginInfo.pwdEncrypted = res;$.ajax({url: staffLogin_url,type: method_post,async: true,dataType: "JSON",data: loginInfo,success: function(data){layer.close(loading);if(data){if(data.ERROR != "EC_NoError"){if(data.msg){layer.msg(data.msg);}else{layer.msg("手机号码或密码错误");}isToSend = true;return;}window.location.href = "../home.bx";}else{isToSend = true;layer.msg("登录失败,公司编号错误");}},error: function(){isToSend = true;layer.close(loading);layer.msg("服务器错误");}});}else{isToSend = true;layer.close(loading);layer.msg("登录失败");}},error: function(){isToSend = true;layer.close(loading);layer.msg("服务器错误");}});return false;})

3、后端生成RSA公钥的模数和指数。

(1)将生成的modulus模数和exponent指数放在RSAInfo类:

RSAInfo rsa = generateRSA(staff.getPhone());public RSAInfo generateRSA(String id) throws Exception {HashMap<String, Object> map = RSAUtils.getKeys();RSAPublicKey publicKey = (RSAPublicKey) map.get("public");mapRSA.put(id, map);String modulus = publicKey.getModulus().toString(16);String exponent = publicKey.getPublicExponent().toString(16);RSAInfo rsa = new RSAInfo();rsa.setExponent(exponent);rsa.setModulus(modulus);return rsa;}

(2)生成RSA公钥和私钥,放在hashmap中:

/*** 生成公钥和私钥* * @throws NoSuchAlgorithmException**/public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException {HashMap<String, Object> map = new HashMap<String, Object>();KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();map.put("public", publicKey);map.put("private", privateKey);return map;}

(3)将公钥和私钥信息以手机号为key保存到hashmap缓存,用于后面的解密:

HashMap<String, Object> map = RSAUtils.getKeys();RSAPublicKey publicKey = (RSAPublicKey) map.get("public");mapRSA.put(id, map);

(4)获取公钥的模数和指数:

String modulus = publicKey.getModulus().toString(16);String exponent = publicKey.getPublicExponent().toString(16);RSAInfo rsa = new RSAInfo();rsa.setExponent(exponent);rsa.setModulus(modulus);

4、将公钥的模数和指数返回给前端。

params.put("rsa", rsa);params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_NoError.toString());params.put(KEY_HTMLTable_Parameter_msg, staffBO.getLastErrorMessage());logger.info("返回的数据=" + params);return JSONObject.fromObject(params, JsonUtil.jsonConfig).toString();

5、前端根据公钥的模数和指数对密码进行加密。

获取模数和指数:

success : function(data){var modulus = data.rsa.modulus;var exponent = data.rsa.exponent;var rsa = new RSAKey();rsa.setPublic(modulus, exponent);var res = rsa.encrypt(password);

对密码进行加密:

// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
function RSAEncrypt(text) {var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);if(m == null) return null;var c = this.doPublic(m);if(c == null) return null;var h = c.toString(16);if((h.length & 1) == 0) return h; else return "0" + h;
}

6、前端将手机号和密码密文传递给后端。

if(res){loginInfo.pwdEncrypted = res;$.ajax({url: staffLogin_url,type: method_post,async: true,dataType: "JSON",data: loginInfo,success: function(data){layer.close(loading);if(data){if(data.ERROR != "EC_NoError"){if(data.msg){layer.msg(data.msg);}else{layer.msg("手机号码或密码错误");}isToSend = true;return;

7、后端使用私钥对密码密文进行解密。

根据手机号key找到对应的私钥进行解密:

String pwd = decrypt(((BaseAuthenticationModel) bmIn).getKey(), sPasswordEncrypted);if (pwd == null) {return null;}

解密密文:

public String decrypt(String key, String sPasswordEncrypted) {lastErrorCode = ErrorInfo.EnumErrorCode.EC_NoError;lastErrorMessage = "";HashMap<String, Object> map = mapRSA.get(key);if (map == null) {return null;}RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");//String pwd = "";try {pwd = RSAUtils.decryptByPrivateKey(sPasswordEncrypted, privateKey);if (!FieldFormat.checkRawPassword(pwd)) {lastErrorCode = ErrorInfo.EnumErrorCode.EC_WrongFormatForInputField;lastErrorMessage = FieldFormat.FIELD_ERROR_Password;logger.info(FieldFormat.FIELD_ERROR_Password);return null;}// logger.info("String decrypted=" + pwd);} catch (Exception e) {logger.info(e);lastErrorCode = EnumErrorCode.EC_Hack;return null;}return pwd;}

8、后端验证账号密码是否正确,完成登录验证。

DataSourceContextHolder.setDbName(dbName);BaseModel bm = retrieve1Object(BaseBO.SYSTEM, iUseCaseID, bmIn);String md5 = MD5Util.MD5(pwd + BaseAction.SHADOW);if (md5 == null) {lastErrorCode = ErrorInfo.EnumErrorCode.EC_OtherError;return null;}if (md5.equals(((BaseAuthenticationModel) bm).getSalt())) {return (BaseAuthenticationModel) bm;} else {lastErrorCode = ErrorInfo.EnumErrorCode.EC_NoSuchData;}

Java使用RSA算法实现安全登录相关推荐

  1. 编程利用Java实现RSA算法

    目录 1.使用说明 2.运行截图 3.总体设计 3.1类和函数 3.2结构说明 4.详细设计 5.源码 1.使用说明 本程序利用eclipse使用Java语言编写.使用该程序可利用eclipse打开源 ...

  2. Java数字签名——RSA算法

    数字签名:带有密钥(公钥,私钥)的消息摘要算法. 验证数据的完整性,认证数据的来源,抗否性 OSI参考模型 私钥签名,公钥验证 签名算法:RSA,DSA,ECDSA 算法1 :RSA MD,SHA两类 ...

  3. java 大整数编程_Java编程--RSA算法中的大整数运算

    Java编程–RSA算法中的大整数运算 RSA原理浅析 RSA是利用陷门单向函数实现的,其安全基础依赖于大整数的分解问题的难解性 算法过程 为了加深对RSA算法的了解,接下来通过简单的一个例子来分析一 ...

  4. 经典非对称加密算法:RSA算法原理、实现详解(C++、Java)

    目录 零.写在最前 参数说明 一.RSA算法原理介绍 二.实验步骤(含实验方法与关键代码) 1. 创建项目 2. 设计加密.解密的总体流程 3. 设计素数类PrimeNum,包括两个静态方法 4. 设 ...

  5. 一个基于RSA算法的Java数字签名例子

    ====================================================== 注:本文源代码点此下载 ================================= ...

  6. DES和RSA算法的java实现

    2019独角兽企业重金招聘Python工程师标准>>> 一.对称加密算法 对称加密算法是应用较早的加密算法,技术成熟.在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过 ...

  7. java rsa 128_如何用java实现128位密钥的RSA算法

    展开全部 import javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; impor ...

  8. java处理加密文件---实现RSA算法

    1  RSA算法的原理如下: 1.1原理      假设我们需要将信息从机器A传到机器B,首先由机器B随机确定一个Key,我们称之为密匙private_key,将这个可KEY始终保存在机器B中而不发出 ...

  9. Java代码实现非对称加密RSA算法示例

    非对称加密:有两把密钥:使用公钥加密,必须使用私钥解密:或者使用私钥加密,必须使用公钥解密 加解密核心类:Cipher 下面代码是使用RSA算法加解密的一个示例,实现过程包括:生成密钥对,把公钥和私钥 ...

最新文章

  1. 计算机二进制加减符号,(带符号的二进制数的表示方法及加减法运算).ppt
  2. 33行代码AC——例题6-5 移动盒子(Boxes in a Line, UVa 12657)——解题报告
  3. Android 系统(171)---OrmLite数据库框架,Picasso框架,Okio框架,OKHttp框架
  4. 【王道操作系统笔记】操作系统的发展和分类
  5. 【精讲版】上位机C#/.NET与西门子PLC通信
  6. java小写金额转大写金额_java转换小写金额为大写金额
  7. html把div做成透明背景,DIV半透明层 CSS来实现网页背景半透明
  8. 5+API实现微信分享功能
  9. 计算机奖项含金量排名,2019五大学科竞赛含金量排名
  10. excel中按出生日期排序公式
  11. 网页自动关机代码HTML,电脑如何自动关机
  12. 中兴微型计算机,售价2698元起!中兴首款5G视频手机AR线上发布
  13. OVQQ框架-一个免费的QQ机器人框架
  14. url短网址 java_url.cn短网址生成api接口(腾讯短链接url生成)
  15. 消防火灾联动报警系统中环网冗余型CAN转光纤的CAN光端机应用
  16. [分享]错误“应用程序Xcode的这个版本不能与此版本的OS X配合使用”以及Mac源码和IOS开发资料分享
  17. “希希敬敬对”团队作业——敏捷冲刺6
  18. 并购潮背后 英特尔能否跨域移动成为AI芯片老大
  19. 梦想CAD控件com接口界面控制右键弹出菜单
  20. 前端使用xlsx.core.min.js读取excel内容

热门文章

  1. C学习笔记——(4)数组和字符串说明,以及冒泡排序法
  2. 基于FPGA视频图像处理系统设计
  3. Java容器(集合)
  4. linux源码网址,可以在这里找到很多开源的驱动
  5. 提交SVN时出现目录obstructed的解决办法·
  6. 普渡大学计算机图形,普渡大学计算机图形学技术研究生语言及申请要求-费用-课程设置...
  7. matlab闭式网络潮流计算,大工20秋《电力系统分析》在线作业2满分
  8. 虚拟机安装mysql数据库
  9. Liunx下AWVS全自动探测漏洞工具の介绍及安装
  10. VMware12下安装Windows7虚拟机---详细多图教程(沙盒环境)