.NET Core登录控制器如何集成MD5Encryption实现密码解密校验
你无法解密得到密码明文的根本原因是认知偏差:数据库中存储的admin用户密码值2fe3cb9e21922819e79a2781af74e36d是32位小写十六进制格式的MD5单向哈希值,是GetMd5Hash()方法的输出结果,并非Encrypt()方法生成的TripleDES对称加密密文(3DES密文为Base64编码格式,字符集、长度和该值完全不匹配)。
MD5属于单向哈希算法,不存在逆向解密为明文的可能性,你编写的Decrypt方法仅用于解密3DES对称加密的内容,和MD5哈希值完全不兼容,强行调用只会抛出格式转换异常。
你当前的登录逻辑是直接将前端传入的哈希值与数据库存储值做等值比对,完全没有关联加密工具类,且存在明显安全隐患:前端直接传哈希值的情况下,攻击者拖库拿到哈希值即可直接登录,无需知道明文密码。
密码校验的正确逻辑永远是「用户传入明文密码→后端用相同规则计算哈希→与数据库存储的哈希值做比对」,不需要解密数据库存储的密码哈希。你的3DES加解密方法仅适用于需要可逆还原的敏感场景(比如你已经实现的数据库连接字符串解密),不适合用于密码存储校验。
按以下步骤改造即可打通逻辑:
- 第一步:引入工具类依赖
在LoginController所在的项目中添加对MD5Encryption类所在命名空间Vantage.DataAccessLayer的引用,确保控制器可以直接调用加密工具类的静态方法。 - 第二步:改造登录校验逻辑
调整接口入参规则:前端只传递用户名、明文密码,不传递哈希值;后端收到请求后,调用GetMd5Hash()方法对用户传入的明文密码做哈希计算,再和数据库中存储的哈希值做比对。改造后的登录接口代码如下:
[HttpPost("login")] public IActionResult Login([FromBody] AvLogin avLogin) { // 基础参数校验 if (avLogin == null || string.IsNullOrWhiteSpace(avLogin.Id) || string.IsNullOrWhiteSpace(avLogin.PasswordHash)) { return BadRequest(new { StatusCode = 400, Message = "用户名和密码不能为空" }); } // 调用工具类计算传入明文的MD5哈希 string inputPasswordHash = MD5Encryption.GetMd5Hash(avLogin.PasswordHash); // 比对用户名+哈希值匹配用户 var user = _context.AvLogins.FirstOrDefault(a => a.Id == avLogin.Id && a.PasswordHash == inputPasswordHash); if (user != null) { return Ok(new { StatusCode = 200, Message = "Logged in Successfully" }); } // 用户名密码不匹配返回401而不是404,符合HTTP语义 return Unauthorized(new { StatusCode = 401, Message = "用户名或密码错误" }); }
- 第三步:明确工具类的使用边界
保留Encrypt/Decrypt方法用于需要可逆解密的场景(比如配置文件中敏感信息加解密、你已经实现的DecryptEntityCon连接字符串解密逻辑),不要用这两个方法处理密码校验逻辑。
改造完成后可以先做本地验证:调用MD5Encryption.GetMd5Hash("你已知的admin明文密码"),如果输出结果等于2fe3cb9e21922819e79a2781af74e36d,说明哈希计算规则和数据库存储规则完全匹配,登录流程即可正常跑通。
补充安全提示:你当前使用的无盐MD5、ECB模式3DES都属于已被破解的不安全算法,后续版本迭代建议将密码存储替换为PBKDF2、Argon2等带盐的慢哈希算法,对称加密替换为AES-GCM认证加密模式,避免安全风险。
内容的提问来源于stack exchange,提问作者Pre

