登录过程RSA加密传输

为了控制和记录访问,很多系统都有登录页面,输入账户、密码和验证码后提交到服务器。在客户端和服务器之间传输数据时,需要传输加密过的数据,以免数据泄露,本文试用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>
    <!--RSA加密代码引入-->
    <script src="~/Scripts/crypto/BigInt.js"></script>
    <script src="~/Scripts/crypto/RSA.js"></script>
    <script src="~/Scripts/crypto/Barrett.js"></script>
    <!--Base64编码代码引入-->
    <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;
            }
            
            //先处理为Base64编码以便传输
            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>

 服务器端使用MVC框架,代码如下:

    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;
            
            //将私钥存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);
            //BASE64解码
            byte[] bytes = Convert.FromBase64String(sLoginPwd);
            obj.LoginPwd = Encoding.UTF8.GetString(bytes);

            /*生产环境要加密后再和数据库比对,此处数据库使用明码,省略这一步*/
            //查询登录对象
            obj = new SysAdminsMge().SysLogin(obj);

            //返回视图
            if (obj == null)
            {
                return Content("0");
            }
            else
            {
                //清除私钥
                Session.Remove("privatekey");
                Session["CurrentAdmin"] = obj;
                //生成认证票据
                FormsAuthentication.SetAuthCookie(obj.LoginName,true);
                return Content("1");
            }
        }

 

posted @ 2019-11-14 23:42  老余的水壶  阅读(1224)  评论(0)    收藏  举报