浏览器的安全随机与哈希:密码生成、UUID 与 SHA-256 实现

简介: 浏览器中三类“随机字符串”需求本质不同:密码需密码学安全随机源(如`crypto.getRandomValues`),UUID(v4/v7)用于唯一标识对象,SHA-256用于校验内容一致性。混用会引入安全风险——UUID非密钥,SHA-256不可存密码,`Math.random()`不适用于认证场景。(239字)

浏览器里经常有三类“看上去都像随机字符串”的需求:

  • 给测试账号生成密码;
  • 给一条记录分配唯一 ID;
  • 给下载文件或文本生成校验值。

它们的目标不同,不能混着用。

密码需要不可预测;UUID 用于标识对象;SHA-256 用于判断字节内容是否一致。把 UUID 当 API 密钥、把 SHA-256 当密码存储方案,或者用 Math.random() 生成密码,都会留下不必要的风险。

目标 合适方案 不适合做什么
生成密码或令牌 密码学安全随机数 用作内容校验
标识数据库记录或请求 UUID v4 / v7 充当登录凭据
校验文件或文本是否变化 SHA-256 加密、签名、存储密码

一、生成密码:随机源比字符表更重要

下面这种写法很常见:

const chars = "*********************************************";
const value = chars[Math.floor(Math.random() * chars.length)];

它适合抽奖动画、界面效果和普通模拟数据,不适合密码。Math.random() 不是密码学安全随机源,攻击者在某些条件下可能推测后续输出。

浏览器需要使用 Web Crypto API:

const bytes = new Uint32Array(1);
crypto.getRandomValues(bytes);

console.log(bytes[0]);

crypto.getRandomValues() 提供适合密码学用途的随机值;Math.random() 则明确属于非密码学随机来源。MDN 的 getRandomValues 文档对此有清晰区分。

取字符时别忽略模偏差

假设字符表有 62 个字符,随机值范围是 0 到 2³² - 1。直接取模:

index = randomValue % 62;

并不能让每个字符完全等概率,因为 2³² 不能被 62 整除。前一部分字符会多一点机会被选中。

常见解决方式是拒绝采样:只接受落在某个可被字符表长度整除的随机范围内的值。

function secureIndex(maxExclusive) {
   
  if (!Number.isInteger(maxExclusive) || maxExclusive < 1) {
   
    throw new Error("字符表不能为空");
  }

  const limit = Math.floor(2 ** 32 / maxExclusive) * maxExclusive;
  const values = new Uint32Array(1);

  do {
   
    crypto.getRandomValues(values);
  } while (values[0] >= limit);

  return values[0] % maxExclusive;
}

之后再根据索引取字符:

function choose(chars) {
   
  return chars[secureIndex(chars.length)];
}

如果密码策略要求至少包含大写、小写、数字和符号,最容易写出的实现通常是“每类先放一个字符,再打乱”。这能满足规则,但不同密码组合出现的概率不一定一致。

更稳妥的做法是:从完整字符表中等概率生成整段密码,检查是否满足策略;不满足就重新生成。只要每次候选密码的生成分布一致,所有符合规则的结果也会保持等概率。

需要生成独立密码、调整字符集和长度,或检查密码策略是否满足站点要求时,可以使用 Password Generator。它在浏览器本地使用 Web Crypto,并用拒绝采样避免取模偏差。

密码生成后仍有几个现实问题:

  • 每个服务应使用不同密码;
  • 密码管理器比手动记忆更可靠;
  • 剪贴板可能被其他软件读取,复制后应避免长时间停留;
  • 密码强度无法防住钓鱼页面、终端恶意软件和重复使用。

二、UUID:标识符不是秘密

UUID 常用于数据库主键、日志关联 ID、任务 ID 和临时资源名。

浏览器可以直接生成 UUID v4:

const id = crypto.randomUUID();

console.log(id);
// 例如:36b8f84d-df4e-4d49-b662-bcde71a8764f

crypto.randomUUID() 在安全上下文中生成基于密码学安全随机数的 v4 UUID,结果是 36 个字符的标准文本形式。MDN 的 randomUUID 文档给出了接口和适用范围。

UUID v4 的大部分有效载荷来自随机数据,适合不依赖时间顺序的场景。

UUID v7 则在开头放入 Unix 毫秒时间戳,剩余非保留位使用随机数据。它在按创建时间排序的数据库索引中通常更友好:

UUID v4:随机数据为主
UUID v7:毫秒时间戳 + 随机数据

UUID v7 的时间特征也意味着它不是隐私字段。看到一个 v7 UUID,可以从中推断大致生成时间。同一毫秒内生成的多个 v7 UUID,尾部仍是随机的,因此不能把它当作严格的创建顺序。

UUID 的版本、变体和布局由 RFC 9562 定义。需要生成 v4、v7,或检查已有 UUID 的版本与文本格式时,可以使用 UUID Generator。

无论是 v4 还是 v7,都不应承担授权职责:

UUID ≠ 密码
UUID ≠ API Key
UUID ≠ Session Token

如果一个资源 URL 只靠 UUID 保护,例如 /download/550e8400-e29b-41d4-a716-446655440000,服务端仍应验证当前用户是否有权限访问资源。UUID 可以减少碰撞,不等于建立访问控制。

三、SHA-256:比较的是字节,不是“文件名”

SHA-256 接收任意长度的字节,输出固定 256 位摘要。输入只要有一点变化,摘要通常就会完全不同。

浏览器中可以这样计算 UTF-8 文本的 SHA-256:

async function sha256Hex(text) {
   
  const bytes = new TextEncoder().encode(text);
  const buffer = await crypto.subtle.digest("SHA-256", bytes);

  return Array.from(new Uint8Array(buffer))
    .map(byte => byte.toString(16).padStart(2, "0"))
    .join("");
}

console.log(await sha256Hex("hello"));

SubtleCrypto.digest() 接收完整字节数据并返回摘要。它支持 SHA-256、SHA-384 和 SHA-512;SHA-1 不应再用于需要密码学安全性的场景。MDN 的 digest 文档还指出,该接口不支持流式输入,文件需要完整读入内存后才能计算。

同一段“看起来一样”的文本,字节不一定相同:

hello
hello\n
hello\r\n

它们会得到不同摘要。文件校验也一样,比较的是文件内容,不是文件名、大小或修改时间。

常见场景是下载校验:

本地文件 → SHA-256 → 与发布方给出的 SHA-256 对比

摘要一致只能证明两份字节内容一致。它不能证明文件安全,也不能证明网页上的预期摘要来自真正的发布者。预期值本身应从可信的发布渠道获取;需要确认发布者身份时,应使用数字签名或其他认证机制。

需要计算文本或本地文件的 SHA-256、SHA-384、SHA-512,并和预期摘要进行核对时,可以使用 Hash Generator。它支持十六进制和 Base64 两种摘要表示,输入在浏览器中处理。

四、哈希不是加密,也不能直接保存密码

哈希、加密和编码常被写在同一段需求里,但职责完全不同:

技术 是否可还原 常见用途
SHA-256 不可逆 文件完整性、内容指纹
AES 等加密 持有密钥可还原 保存需要重新读取的敏感数据
Base64 可逆 文本化表示字节
Argon2id、bcrypt、scrypt 不可逆且有意放慢 密码存储

不能这样存密码:

const stored = await sha256Hex(password);

SHA-256 是快速通用摘要。攻击者拿到数据库后,可以高速尝试大量候选密码并对比摘要。密码存储应使用专门的慢哈希算法,并为每个密码使用独立盐值。

OWASP 当前建议优先使用 Argon2id;在不具备条件时可选择 scrypt、bcrypt 或 PBKDF2 等方案。其 密码存储指南明确指出,SHA-256 等快速摘要算法不适合存储密码。

五、三个工具如何放在一次开发流程里

假设要给一个内部文件处理服务补齐基础能力,可以按下面的边界拆分:

创建测试账户
→ 生成独立随机密码

创建上传任务
→ 生成 UUID v4 或 UUID v7

用户上传文件
→ 计算 SHA-256

下载或转存文件
→ 再次计算 SHA-256 并核对

其中:

  • 随机密码保护账户;
  • UUID 标记任务和文件记录;
  • SHA-256 检查内容是否发生变化。

三者都可能出现在同一个系统里,却没有一个能替代另外两个。把用途分清,代码会简单很多,安全边界也更容易审查。

相关文章
|
10天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7742 13
|
8天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1668 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1445 1
|
8天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1302 11
|
22天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3694 10
|
7天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)
|
16天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1784 1

热门文章

最新文章