如何使用Rust WebAssembly优化前端Vue项目MD5效率
一、前言:
MD5为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。
MD5是一种哈希算法,主要用于数据完整性校验、文件传输验证等场景,但因存在碰撞漏洞,不适用于高安全性需求。MD5具有固定长度的输出、抗修改性和抗碰撞性等特点,但需注意其存在破解方法,可通过多重加密和加盐增加安全性。MD5在信息技术领域应用广泛,确保数据的完整性和安全性。MD5通过一系列的逻辑函数、位运算和加法运算,将输入的任意长度的数据转换成固定长度的哈希值。这个过程涉及填充、分组、附加长度值、初始化缓冲区、迭代处理和最终输出。MD5被认为是安全的哈希函数,因为从理论上讲,它能够抵抗碰撞攻击(即找到两个不同的输入产生相同哈希值的情况)。
- 数据指纹生成:将任意长度数据转换为固定128位哈希值(32位十六进制字符串),微小修改会导致哈希值完全变化 。
- 不可逆性:无法通过哈希值还原原始数据,但因碰撞漏洞,不适用于密码存储或数字签名 。
主要应用场景:
- 文件传输完整性校验:通过对比源文件和接收文件的MD5值,验证传输过程中数据是否受损 。
- API数据校验:在接口调用中,通过校验请求数据的MD5值确保数据未被篡改 。
- 数据库优化:对长文本生成MD5哈希值作为索引,提升查询效率 。
Rust 实现 MD5 算法 - 用户密码加盐:
对于用户密码加密最高境界就是:别人获得你数据库的用户资料别人也没有办法获知密码.要达到就要有一套复杂的加密规则,一般常用的规则比如:
# 这样避免碰库用MD5来攻击服务器
MD5(MD5(用户名+用户密码)+MD5(KEY+项目名+公司名))
Rust中实现MD5加密可通过多种方式完成,包括使用标准库、第三方库或WebAssembly集成。这里为了演示Vue环境中的MD5加密,所以,这里推荐使用WebAssembly集成,以下是关键实现方法:
使用:ml-search-more[wasm-bindgen]将Rust代码导出为.wasm文件:
Cargo 是 Rust 的包管理器,用于 Rust 包的发布、下载、编译等,可以按需索取你需要的包。其中 md5 就是一会要进行 md5 加密的算法包,wasm-bindgen 是帮助 wasm 和 js 进行交互的工具包,抹平实现细节,方便两个内存空间进行通讯。
[dependencies]
wasm-bindgen = "0.2.83"

编写导出函数:
#[wasm_bindgen]
pub fn md5(input: &str) -> String {
format!("{:x}", Md5::digest(input))
}

使用:ml-search-more[wasm-pack]打包并生成.wasm文件。
这是 wasm-pack 构建的是库目标,项目当时只有 src/main.rs,存在 [lib] crate-type = [“cdylib”, “rlib”] 的情况下,所以需要在 src/lib.rs 中增加 #[wasm_bindgen] 注释,如下:
新增了 src/lib.rs 并导出一个 MD5 计算函数:
- 文件 src/lib.rs 增加 #[wasm_bindgen] pub fn md5_hex(input: &str) -> String ,返回输入字符串的 MD5(十六进制)。
- 这满足 wasm-pack build --target web 对库的要求。
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn md5_hex(input: &str) -> String {
let digest = md5::compute(input.as_bytes());
format!("{:x}", digest)
}
wasm-pack
以上各个工具链看着复杂,官方开发支持的 wasm-pack 工具可以屏蔽这一切细节,基于 wasm32-unknown-unknown 工具链可快速实现 Rust -> wasm -> npm 包的编译打包,从而实现在 web 上的快速调用,窥探 wasm-npm 包这头“大象”只需要如下几步:
-
- 使用 rustup 安装rust
-
- 安装 wasm-pack
-
- wasm-pack new hello-wasm.
-
- wasm-pack build.
-
- pkg 目录下产物就是可以被正常调用的 node_module
最后,使用wasm-pack构建项目:
wasm-pack build --target web

借助 wasm_bindgen 可以快速将方法导出给 js 进行调用,从而不需要关心内存通信的细节。最终通过 wasm-pack build 构建出包(在目录 pkg 下),可以直接在 web 进行引用了,产物主要包含以下几部分
├── package.json
├── README.md
├── *.ts
├── index_bg.wasm:生成 wasm 文件,被index.js进行调用
├── index.js:这个就是最终被 ECMAScript 项目引用的模块文件,里边包含定义的方法以及一些自动生成的胶水函数,利用 TextEncoder 实现内存之间的数据通信。
前端使用方式(示例):
- 导入生成的包后,调用 md5_hex(“hello”) 即可得到 5d41402abc4b2a76b9719d911017c592 。

说明:
- 之前你把 MD5 函数放在 main.rs ,这对 CLI 没问题,但 wasm-pack 只构建库,所以需要 src/lib.rs 。
- 如果你还需要在 CLI( main.rs )里对生成的文件计算并打印 MD5,我可以在 main.rs 保存 Excel 后读取该文件并打印其 MD5;当前先保证 wasm-pack 构建库正常。

Vue 中使用 MD5 加密:
import MD5 from 'js-md5';
//使用
MD5.md5("MD5编码");

接下来,可以将生成的 pkg 目录拷贝到 Vue 项目中,并在项目中引用。
import * as wasm from "./pkg";
wasm.digest('xxx');
构建出的 wasm pkg 包引入 web 项目中,使用 webpack@4 进行打包编译,甚至不需要任何其他的插件便可支持。
Rust 与 Vue 使用 MD5 加密对比:
针对字符串进行 md5 加密,粗略的速度对比:
| 加密1次时间(ms) | 加密10次时间(ms) | 算法依赖包 |
|---|---|---|
| js版本md5 | ~63 | ~1623 |
| wasm版本md5 | ~6 | ~142 |
从数据层面来看,wasm 的性能优势显而易见。但同时也发现在 100 次的时候,性能数据差值虽然扩大,但是比值却相比一次加密缩小。原因是在多次加密的时候,js 和 wasm 的通信成本的占比逐渐增高,导致加密时间没有按比例增长,也说明 wasm 实际加密运算的时间比结果更小。这其实也表明了了 wasm 在 web 上的应用场景:重计算、轻交互,例如音视频/图像处理、游戏、加密。
总结:
Rust的WebAssembly(wasm) 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,由 w3c 制定出的新的规范。目的是在一些场景下能够代替 JS 取得更接近原生的运算体验,比如游戏、图片/视频编辑、AR/VR。说人话,就是可以体积更小、运行更快。wasm 有两种表示格式,文本格式和二进制格式。二进制格式可以在浏览器的 js 虚拟机中沙箱化运行,也可以运行在其他非浏览器环境中,比如常见的 node 环境中等;运行在 Web 上是 wasm 一开始设计的初衷,所以实现在浏览器上的运行方法非常简单。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)