为了控制和记录访问,很多系统都有登录页面,输入账户、密码和验证码后提交到服务器。在客户端和服务器之间传输数据时,需要传输加密过的数据,以免数据泄露,本文试用RSA加密实现这一过程;
客户端代码:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>后台管理登录</title> <link href="~/Areas/HotelWebMge/Styles/AdminCss.css" rel="stylesheet" type="text/css" /> <script src="~/Scripts/jquery-1.8.2.js"></script> <script src="~/Scripts/crypto/BigInt.js"></script> <script src="~/Scripts/crypto/RSA.js"></script> <script src="~/Scripts/crypto/Barrett.js"></script> <script src="~/Scripts/crypto/Base64.js"></script> <script type="text/javascript">
$(function () { //键盘登录 $(document).keydown(function (event) { //Enter键登录 if (event.keyCode == 13) { login(); } }); //按钮登录 $('#btnlogin').click( login ); });
function login() { var txtLoginId = $('#txtLoginId').val(); //加密密码后赋值更新 var txtLoginPwd = $('#txtLoginPwd').val(); if (txtLoginPwd.length <= 5) { $('#ItaInfo').text("密码不能少于6位!"); return; } var base = new Base64(); var baseLoginPwd = base.encode(txtLoginPwd); var EncryptedPwd = cmdEncrypt(baseLoginPwd); //$('#txtLoginPwd').val(EncryptedPwd); var sdata = { "LoginId": txtLoginId, "LoginPwd": EncryptedPwd }; //异步提交 $.ajax({ url: '@Url.Content("~/HotelWebMge/SysAdmins/SysLogin")', type: 'post', //data: $('#form1').serialize(), data: sdata, beforeSend: function () { $('#ItaInfo').text("...正在提交...请稍候!"); //alert($('#form1').serialize()); }, dataType: 'JSON', error: function (xhr, status, error) { $('#ItaInfo').text("输入字符串的格式不正确,登录失败!"); }, success: function (data) { //登录成功 if (data == "1") { window.location.href = '@Url.Action("Index", "Company", new{area="HotelWebMge"})'; } else { $('#ItaInfo').text("用户名或密码错误!"); }; }, complete: function () { //$('#ItaInfo').empty(); } }); }
//分段加密,2019-06-11 function cmdEncrypt(value) { setMaxDigits(130); var key = new RSAKeyPair("@ViewBag.strPublicKeyExponent", "", "@ViewBag.strPublicKeyModulus"); //获取组块大小 var maxLength = key.chunkSize; //生成长度正则 var seg = new RegExp('.{1,' + maxLength.toString() + '}', 'g'); try { var lt = ""; var ct = ""; if (value.length > maxLength) { lt = value.match(seg); lt.forEach(function (entry) { var t1 = encryptedString(key, entry); ct += t1; }); return (ct); } var t = encryptedString(key, value); return t; } catch (ex) { return false; } //var valueRtn = encryptedString(key, value); //return valueRtn; }
</script> </head> <body> <form id="form1"> <div id="container"> <div id="top"> </div> <div id="content"> <div id="loginimg"> <img src="~/Areas/HotelWebMge/Styles/Images/loginimg.jpg" alt="" /> </div> <div id="logindiv"> <div id="ltitle"> 管理员登录 </div> <div class="litem"> 登录账号:<input name="LoginId" type="text" id="txtLoginId" class="txt" /> </div> <div class="litem"> 登录密码:<input name="LoginPwd" type="password" id="txtLoginPwd" class="txt" onpaste="return false" oncontextmenu="return false" oncopy="return false" oncut="return false" /> </div> <div class="litem"> <input type="button" name="btnlogin" value="马上登录" id="btnlogin" class="btncss" /> </div> <div class="loginInfo" id="ItaInfo"></div> </div> </div> <div id="footer"> <div id="bq"> 版权所有 Copyright(C)2010-2020 </div> </div> </div> </form> </body> </html>
服务器代码:
public class SysAdminsController : Controller { /*参考网站如下,2019-01-16 * https://www.cnblogs.com/guogangj/archive/2012/03/05/2381117.html * https://blog.csdn.net/angle_greensky110/article/details/48293653 * https://www.cnblogs.com/wenghaowen/p/3912132.html * https://www.cnblogs.com/alunchen/p/5758585.html * * https://blog.csdn.net/xiaouncle/article/details/54913102 */ // // GET: /HotelWebMge/SysAdmins/ /// <summary> /// 后台管理登录入口 /// </summary> /// <returns></returns> public ActionResult AdminLogin() { RSACryptoServiceProvider rsaKeyGenerator = new RSACryptoServiceProvider(1024); //产生一对公钥私钥 //把公钥适当转换,准备发往客户端 RSAParameters parameter = rsaKeyGenerator.ExportParameters(true); string strPublicKeyExponent = StringHelper.BytesToHexString(parameter.Exponent); string strPublicKeyModulus = StringHelper.BytesToHexString(parameter.Modulus); //传递公钥到页面 ViewBag.strPublicKeyExponent = strPublicKeyExponent; ViewBag.strPublicKeyModulus = strPublicKeyModulus; //BitConverter.ToString("fgf") //将私钥存Session中,生产环境可以存储到数据库或服务器本地硬盘 Session["privatekey"] = rsaKeyGenerator.ToXmlString(true); return View("AdminLogin"); } /// <summary> /// 后台登录处理 /// </summary> /// <returns></returns> public ActionResult SysLogin(SysAdmins obj) { //取出私钥 string privatekey = Session["privatekey"].ToString(); //解密密码 RSACryptoServiceProvider rsaKeyGenerator = new RSACryptoServiceProvider(1024); rsaKeyGenerator.FromXmlString(privatekey); //加载密文,2019-06-11 byte[] dataEnc = StringHelper.HexStringToBytes(obj.LoginPwd); int keySize = rsaKeyGenerator.KeySize / 8; byte[] buffer = new byte[keySize]; MemoryStream msInput = new MemoryStream(dataEnc); MemoryStream msOutput = new MemoryStream(); int readLen = msInput.Read(buffer, 0, keySize); while (readLen > 0) { byte[] dataToDec = new byte[readLen]; Array.Copy(buffer, 0, dataToDec, 0, readLen); byte[] decData = rsaKeyGenerator.Decrypt(dataToDec, false); msOutput.Write(decData, 0, decData.Length); readLen = msInput.Read(buffer, 0, keySize); } msInput.Close(); byte[] result = msOutput.ToArray(); System.Text.ASCIIEncoding ByteConverter = new ASCIIEncoding(); string sLoginPwd = ByteConverter.GetString(result);
byte[] bytes = Convert.FromBase64String(sLoginPwd); obj.LoginPwd = Encoding.UTF8.GetString(bytes);
//生产环境要加密后再和数据库比对,此处数据库使用明码,省略这一步 //查询登录对象 obj = new SysAdminsMge().SysLogin(obj); //返回视图 if (obj == null) { //ViewData["LoginUser"] = "用户名或密码错误!"; //return View(); return Content("0"); } else {//清除私钥 Session.Remove("privatekey"); Session["CurrentAdmin"] = obj; FormsAuthentication.SetAuthCookie(obj.LoginName,true); return Content("1"); } } }