下载完文件怕被改写?写了个前端哈希校验器,上传即算摘要

举报
茉莉风铃 发表于 2026/10/09 11:12:56 2026/10/09
【摘要】 选个本地文件,浏览器当场算出 SHA-256 摘要,用来比对下载完整性,全程不联网、文件不出本机。顺带讲清为什么浏览器原生算不了 MD5。

从网盘、镜像站下完安装包,第一反应该是校验哈希,确认没被中间人篡改。可在线校验网站要把文件传上去,等于把隐私文件也交出去了。我写了个纯前端哈希校验器:选本地文件,浏览器当场算出摘要,文件不出本机。用的是 Web Crypto 的 SHA-256——顺带也讲清楚为什么浏览器原生算不了 MD5。

一、为什么用 SHA-256 而不是 MD5

MD5 因为碰撞漏洞早已不推荐用于安全校验,更现实的是:浏览器原生没有提供 MD5。Web Crypto API(crypto.subtle)只给了 SHA-1/256/384/512,没有 MD5。想在浏览器算 MD5 只能引入第三方库(如 spark-md5),把文件读进内存再自己实现算法。

所以我这版直接用原生 SHA-256,零依赖、速度快,校验下载完整性完全够用。下载站给的如果是 MD5,那就用库补一个,思路一致。

二、读文件 + 算哈希

用 FileReader 把文件读成 ArrayBuffer,交给 crypto.subtle.digest:

async function hashFile(file) {
  const buf = await file.arrayBuffer();          // 读成二进制
  const digest = await crypto.subtle.digest('SHA-256', buf);
  return [...new Uint8Array(digest)]
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');                                    // 转十六进制串
}

file.arrayBuffer() 比老式的 FileReader.readAsArrayBuffer 写法更短。算出来的 digest 是二进制,用展开运算符转成字节数组,每个字节 toString(16) 补零拼成十六进制串——这才是人能读的哈希值。

三、大文件也要稳

几百 MB 的文件一次性读进内存没问题,但超大文件该用流式 crypto.subtle.digest 不支持分块,真要分块得自己攒 buffer。日常场景一次性读足够,记得在算的期间给个"计算中"提示,不然用户以为卡了:

fileInput.addEventListener('change', async () => {
  const file = fileInput.files[0];
  tip.textContent = '计算中…';
  const hex = await hashFile(file);
  tip.textContent = '';
  result.value = hex;
});

哈希算法对比

算法 浏览器原生 输出长度 现状
MD5 否(需库) 128 位 已不推荐用于安全
SHA-1 是 160 位 逐步淘汰
SHA-256 是 256 位 当前主流

下载站给 SHA-256 就直接比;给 MD5 只能靠库,且别拿 MD5 当安全证明。

几个容易踩的点

  • 大小写比对:哈希串有大小写之分,比对前统一 .toLowerCase(),不然 AB 和 ab 被认为不等。
  • ArrayBuffer 只读一次:file.arrayBuffer() 可以反复调,但老式 FileReader 的 result 读一次就废,混用容易踩。
  • 老浏览器兼容:crypto.subtle 要求 HTTPS 或 localhost,用 file:// 直接打开可能拿不到,本地起个静态服务再开。
  • 别拿哈希当加密:哈希是单向的,只能"比对"不能"还原",校验完整性可以,藏秘密不行。

文章总结

前端哈希校验器的核心是 FileReader/arrayBuffer 读文件加 crypto.subtle.digest('SHA-256', buf),再把二进制转十六进制串。选 SHA-256 是因为它浏览器原生支持、且比 MD5 更安全——MD5 既不安全也不被原生提供,硬要只能引库。文件全程在本地内存算,不上传不变服务器,校验下载包完整性正好。比对时统一大小写,老环境注意 crypto.subtle 要 HTTPS 才生效。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。