HTML5的input[type="password"]仅隐藏字符显示且不加密,提交时仍为明文;前端哈希无法替代服务端强哈希处理,必须强制HTTPS、服务端用bcrypt/Argon2加盐哈希、前端仅做辅助防护。

HTML5 本身不提供密码加密能力,input[type="password"] 只是屏蔽明文显示,提交时仍是明文——想靠它防泄露,完全无效。
为什么 input[type="password"] 不等于加密
这个属性只做两件事:隐藏字符(显示 ● 或 ⚫)、禁止浏览器自动填充时的明文回显。它不修改值、不调用任何哈希或加密算法,document.getElementById("pwd").value 拿到的就是原始密码字符串。
- 抓包工具(如 Chrome DevTools 的 Network 面板)能直接看到 POST 请求体里的明文密码
- 中间人攻击、恶意插件、控制台执行 JS 都可轻易读取
- 服务端若未做校验,甚至可能把这串“密文”原样存进数据库
前端加盐哈希有用吗?crypto.subtle.digest() 能不能用
技术上可以调用 crypto.subtle.digest() 做 SHA-256 等哈希,但**无法替代服务端密码处理**:
- 前端哈希后仍需把哈希值发给服务端——如果传输过程没 HTTPS,哈希值本身就成了新密码,被截获就能直接登录
- 无法安全加盐:盐必须唯一且保密,前端无法生成并保管用户专属盐值;硬编码一个全局盐,等于没盐
- 彩虹表仍有效:若盐固定 + 算法公开,攻击者可预计算哈希库
- 现代浏览器限制
crypto.subtle必须在安全上下文(HTTPS)中运行,HTTP 站点直接报错
真正该做的三件事(顺序不能错)
防密码泄露不是前端单点任务,而是链路协作:
立即学习“前端免费学习笔记(深入)”;
- 强制全站 HTTPS:否则任何前端加密都白搭,
fetch()或XMLHttpRequest发出的请求都可能被劫持 - 服务端用强哈希(如
bcrypt、Argon2)处理密码:加盐、自适应迭代、防 GPU 暴力破解 - 前端仅做基础防护:启用
autocomplete="new-password"减少密码复用风险;用pattern和title提示强度要求(如pattern="(?=.*\d)(?=.*[a-z]).{8,}"),但绝不用于校验逻辑
最常被忽略的一点:即使前端做了所有“看起来很安全”的操作,只要服务端接收的是明文或弱哈希,整个链条就断了。密码安全的重心永远在服务端存储与传输过程,而不是 input 标签的 type 属性。











