让京东的密码问题从此不再重现(NET篇)

2012年12月,以CSDN为首的密码泄露门第一次出现在互联网中,这样的爆发让我们这些基层程序猿们不可以理解,csdn居然没有把密码加密。哦买噶!!!转眼2016年12月,时隔4年京东电商巨头又一次遭遇了这样的悲催行为。这样的问题,就是密码简单设置导致的。

开篇结束进入正题,我是一枚NET开发者,如果通过密码安全来保护用户的隐私?这里有一个很好的解决方案,首先在项目中做一个枚举如下图:


让平台来设置不同的用户不同的加密方式(Clear可以去掉不用)。

其次,我们在写一个加密服务EncryptionService



    public class EncryptionService
    {        
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="password"></param>
        /// <param name="saltkey"></param>
        /// <param name="passwordFormat"></param>
        /// <returns></returns>
        public string CreatePasswordHash(string password, string saltkey,
            string passwordFormat = "SHA1")
        {
            if (String.IsNullOrEmpty(passwordFormat))
                passwordFormat = "SHA1";
            string saltAndPassword = String.Concat(password, saltkey);

            //return FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPassword, passwordFormat);
            var algorithm = HashAlgorithm.Create(passwordFormat);
            if (algorithm == null)
                throw new ArgumentException("无法识别的哈希名称");

            var hashByteArray = algorithm.ComputeHash(Encoding.UTF8.GetBytes(saltAndPassword));
            return BitConverter.ToString(hashByteArray).Replace("-", "");
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <param name="encryptionPrivateKey"></param>
        /// <returns></returns>
        public string EncryptText(string plainText, string encryptionPrivateKey = "")
        {
            if (string.IsNullOrEmpty(plainText))
                return plainText;
            return MD5Encrypt(plainText, new UTF8Encoding());
        }
                
        public string MD5Encrypt(string input, Encoding encode)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(encode.GetBytes(input));
            StringBuilder sb = new StringBuilder(32);
            for (int i = 0; i < t.Length; i++)
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            return sb.ToString();
        }
        
    }



好了,做好了这两个方法,我们来设计数据库的用户表。


因为是个教程,我没有刻意去设计很好的CodeFirst或是映射。我用的ef。大家凑合看

上图数据库设计



不用太多解释,PasswordFormatId是针对不同用户设计的不同加密方式,即便全部泄露了,解密也要很复杂。

最后在来看看控制器


    public class CustomerController : Controller
    {
        #region Login
        // GET: Customer
        public ActionResult Index(string tip = "")
        {
            var model = new CustomerIndexModel();
            ViewBag.Tip = tip;
            return View(model);
        }

        [HttpPost]
        public ActionResult Login(CustomerIndexModel model)
        {
            var result = new CustomerService().Login(model.LoginName);
            if(result == null)
                return RedirectToAction("Index", new { tip = "该账户不存在" });
            bool Verification = false;
            switch ((PasswordFormat)result.PasswordFormatId)
            {
                case PasswordFormat.Clear:
                    Verification = model.LoginPassword == result.Password;
                    break;
                case PasswordFormat.Encrypted:
                    Verification = new EncryptionService().EncryptText(model.LoginPassword, result.PasswordSalt) == result.Password;
                    break;
                case PasswordFormat.Hashed:
                    Verification = new EncryptionService().CreatePasswordHash(model.LoginPassword, result.PasswordSalt) == result.Password;
                    break;
                default:
                    Verification = new EncryptionService().CreatePasswordHash(model.LoginPassword, result.PasswordSalt) == result.Password;
                    break;
            }
            if (!Verification)
                return RedirectToAction("Index", new { tip = "密码错误" });
            else
                return RedirectToAction("Index", new { tip = "登录成功" });
        }
        #endregion

        #region Register

        public ActionResult Register()
        {
            var model = new CustomerRegisterModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult Register(CustomerRegisterModel model)
        {
            //判定是否录入验证通过
            if (ModelState.IsValid)
            {
                var entity = new Models.Customer {
                    Active = true,
                    Deleted = false,
                    Email = model.Email,
                    LoginName = model.LoginName,
                    Password = model.LoginPassword,
                    Mobile = model.Mobile,
                    //假设加密方式为
                    PasswordFormatId = (int)PasswordFormat.Hashed
                };

                new CustomerService().InsertCusotmer(entity);
                return RedirectToAction("Index", new { tip ="注册成功" });
            }
            return View();
        }
        #endregion
    }

    资源下载地址:http://download.csdn.net/detail/hb12417058/9711008

这个不用过多解释。

大家如果有什么疑问请加群 68848430 咨询。

我会把资源上传上来供大家学习

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值