文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用WebAssembly对前端API请求进行签名

2024-12-02 11:38

关注
  1. 请求重放 (eg. 月饼抢购场景中,程序员通过脚本直接访问接口)
  2. 参数篡改 (eg. 会话劫持场景中,将应该抢购到的月饼归属人改为自己)
  3. 脚本攻击 (eg. 综合前两种场景,使用技术手段构建的请求进行攻击,如信息窃取,漏洞攻击)
  4. 可信客户端请求 (eg. 以上所有场景根因均为访问客户端不可信并不可证伪)

解决方案

  1. 对请求参数+cnonce (客户端生成的一次性随机字符串) 进行hash签名
  2. 以secret作为盐值
  3. 将签名作为header值传递给server端
  4. server端在redis中查验是否已有重复签名,如有重复直接拒绝请求(防止请求重放)
  5. server端对签名值进行校验
  6. 校验通过之后将该签名值作为key值,存入redis

总体流程如下图所示:

代码示例

前端使用示例(TypeScript Vue3 版本):

  1.  
  2. import { onMounted } from "vue"
  3. import initWasm, {sign} from "./pkg/sign.js"; // 通过wasm-pack打包生成的二进制包的入口文件 
  4. import { v4 as uuidv4 } from 'uuid'; // 此示例以生成的UUID作为cnonce随机字符串 
  5.   
  6. onMounted(async () => { 
  7.     await initWasm() 
  8. }) 
  9.   
  10. const sendRequest = () => { 
  11.     const cnonce = uuidv4() 
  12.     const params: EncryptedParams = { 
  13.         name'John'
  14.         age: 23, 
  15.         breed: 'dog'
  16.         ts: Date.now() 
  17.     } 
  18.     const wasmSignature = sign(JSON.stringify(params), cnonce); 
  19.     ... 
  20.     axios.post(something); 
  21.   
  22.  

 

签名机制示例,server端接受到请求时,应该同时获得签名值以及cnonce一次性字符串,按照下面同样的签名顺序进行签名,比对前端传入的签名以及server端生成的签名进行校验:

  1. const encryptedSign = (message: string, cnonce: string): string => { 
  2.   const secret = 'XXXXXXX' // 该签名盐值可以自行生成,生成之后需要重新编译rust应用,生成新的wasm包 
  3.   const hashDigest = sha256(`${cnonce}|${message}`) 
  4.   const hmacDigest = Base64.stringify(hmacSHA512(hashDigest.toString().toUpperCase(), secret)) 
  5.   return hmacDigest.toString().toUpperCase() 

签名机制示例 (rust 版本): 

  1. extern crate wasm_bindgen; 
  2.   
  3. use ring::hmac; 
  4. use ring::digest::{Context, SHA256}; 
  5. use data_encoding::BASE64; 
  6. use data_encoding::HEXUPPER; 
  7. use wasm_bindgen::prelude::*; 
  8.   
  9. #[wasm_bindgen] 
  10. pub fn ron_weasley_sign (message: &str, cnonce: &str) -> String { 
  11.     const SECRET: &str = std::env!("SECRET"); 
  12.   
  13.     let mut context = Context::new(&SHA256); 
  14.     context.update(format!("{}|{}", cnonce, message).as_bytes()); 
  15.     let sha256_result = context.finish(); 
  16.     let sha256_result_str = format!("{}", HEXUPPER.encode(sha256_result.as_ref())); 
  17.   
  18.     let key = hmac::Key::new(hmac::HMAC_SHA512, SECRET.as_bytes()); 
  19.     let mac = hmac::sign(&key, sha256_result_str.as_bytes()); 
  20.     let b64_encoded_sig = BASE64.encode(mac.as_ref()); 
  21.     return b64_encoded_sig.to_uppercase(); 

构建rust源代码,并生成对应的二进制包

首先在项目的github地址

https://github.com/swearer23/ron-weasley 下载源代码

之后按照README文件的步骤安装编译环境(以*nix环境为例)

安装cargo

由于我们使用cargo作为rust环境的管理器,所以第一步安装cargo

安装完成后在命令行输入cargo -v 查看是否安装成功

  1. cargo -v # 可能需要重新启动终端 
  2. Rust's package manager 
  3.  
  4. USAGE: 
  5.     cargo [+toolchain] [OPTIONS] [SUBCOMMAND] 
  6.  
  7. OPTIONS: 
  8.     -V, --version                  Print version info and exit 
  9.         --list                     List installed commands 
  10.         --explain            Run `rustc --explain CODE` 
  11.     -v, --verbose                  Use verbose output (-vv very verbose/build.rs output) 
  12.     -q, --quiet                    No output printed to stdout 
  13.         --color              Coloring: auto, always, never 
  14.         --frozen                   Require Cargo.lock and cache are up to date 
  15.         --locked                   Require Cargo.lock is up to date 
  16.         --offline                  Run without accessing the network 
  17.         --config ...    Override a configuration value (unstable) 
  18.     -Z ...                   Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details 
  19.     -h, --help                     Prints help information 
  20.  
  21. Some common cargo commands are (see all commands with --list): 
  22.     build, b    Compile the current package 
  23.     check, c    Analyze the current package and report errors, but don't build object files 
  24.     clean       Remove the target directory 
  25.     doc, d      Build this package's and its dependencies' documentation 
  26.     new         Create a new cargo package 
  27.     init        Create a new cargo package in an existing directory 
  28.     run, r      Run a binary or example of the local package 
  29.     test, t     Run the tests 
  30.     bench       Run the benchmarks 
  31.     update      Update dependencies listed in Cargo.lock 
  32.     search      Search registry for crates 
  33.     publish     Package and upload this package to the registry 
  34.     install     Install a Rust binaryDefault location is $HOME/.cargo/bin 
  35.     uninstall   Uninstall a Rust binary 
  36.  
  37. See 'cargo help ' for more information on a specific command. 

安装wasm-pack

要构建二进制包,需要一个额外工具 wasm-pack。它会帮助我们把代码编译成 WebAssembly 并构建出适用于web环境的wasm包。使用下面的命令可以下载并安装:

  1. cargo install wasm-pack 

编译wasm

wasm-pack安装成功后,执行下面的命令以编译wasm包

  1. SECRET= wasm-pack build --target=web --release 

替换为你的签名盐值

第一次构建和编译时间会比较长,需要下载依赖的rust库并编译,请耐心等待

如果速度仍然很慢,建议更换cargo国内源

更换 cargo 源

在你的cargo文件夹下新建 config 文件

macos中,文件夹地址在 ~/.cargo 

  1. cd ~/.cargo 
  2. touch config 

然后编辑config文件,添加如下内容: 

  1. [source.crates-io] 
  2. registry = "https://github.com/rust-lang/crates.io-index" 
  3. replace-with = 'ustc' 
  4. [source.ustc] 
  5. registry = "git://mirrors.ustc.edu.cn/crates.io-index" 

即可更换为ustc的源

集成

执行wasm-pack命令打包会得到一个名为pkg的文件夹,位于项目的根目录下

将其放入要使用的前端项目中,即可以像上面代码示例章节所描述的方式进行集成和调用

附录

  • rust 项目地址:https://github.com/swearer23/ron-weasley
  • vue3 调用方式示例项目地址:https://github.com/swearer23/harry-porter (内含有secret=123456的wasm包,可以用于示例)

 

 

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯