当前位置: 首页 > 科技观察

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

时间:2023-03-13 13:39:54 科技观察

后台处理WebAPI请求的服务端安全问题:请求重放(例如抢月饼场景,程序员直接通过脚本访问接口)参数篡改(例如。在session劫持场景中,将本应抢购的月饼的所有者更改为自己)脚本攻击(如结合前两种场景,利用技术手段构造请求进行攻击,如信息窃取、漏洞攻击)Trusted客户端请求(eg.以上所有场景根本原因是接入客户端不可信任不可伪造)解决方案是对请求参数+cnonce(客户端生成的一次性随机字符串)进行哈希签名,使用secret作为salt值,并将签名作为header值传递给服务端终端在redis中检查是否存在重复签名,如果存在重复则直接拒绝请求(以防止请求重播)。服务端对签名值校验通过后,将签名值作为键值,存储到redis中的整体流程如下图所示:代码示例前端使用示例(TypeScriptVue3版本):签名机制示例,服务端收到请求时,同时获取签名值和cnonce一次性字符串,按照如下相同的签名序列进行签名,比较签名p由前端和ser加入验证ver端生成的签名:constencryptedSign=(message:string,cnonce:string):string=>{constsecret='XXXXXXX'//签名salt值可以自己生成,生成后rust应用需要重新编译生成一个新的wasm包.toUpperCase()}签名机制示例(rust版本):externcratewasm_bindgen;usering::hmac;usering::digest::{Context,SHA256};usedata_encoding::BASE64;usedata_encoding::HEXUPPER;usewasm_bindgen::prelude::*;#[wasm_bindgen]pubfnron_weasley_sign(message:&str,cnonce:&str)->String{constSECRET:&str=std::env!("SECRET");letmutcontext=Context::new(&SHA256);context.update(格式!("{}|{}",cnonce,message).as_bytes());letsha256_result=context.finish();letsha256_result_str=format!("{}",HEXUPPER.encode(sha256_result.as_ref()));letkey=hmac::密钥::新(hmac::HMAC_SHA512,SECRET.as_bytes());letmac=hmac::sign(&key,sha256_result_str.as_bytes());letb64_encoded_sig=BASE64.encode(mac.as_ref());returnb64_encoded_sig.to_uppercase();}先在项目的github地址https://github.com/swearer23/ron构建rust源码并生成对应的二进制包-weasley下载源码后,按照README文件中安装编译环境的步骤(以*nix环境为例)安装cargo。由于我们使用cargo作为rust环境的管理器,所以第一步是安装cargo。安装完成后在命令行输入cargo-v查看是否安装成功cargo-v#可能需要重启终端Rust的spackagemanagerUSAGE:cargo[+toolchain][OPTIONS][SUBCOMMAND]OPTIONS:-V,--versionPrintverboseinfoandexit--listListinstalledcommands--explainRun`rustc--explainCODE`-v,--verboseUverboseoutput(-vvveryverbose/build.rsoutput)-q,--quietNooutputprintedtostdout--color着色:自动,始终,never--frozenRequireCargo.lockandcacheareuptodate--lockedRequireCargo.lockisuptodate--offlineRunwithoutaccessingthenetwork--config...Overrideaconfigurationvalue(unstable)-Z...Unstable(nightly-only)flagstoCargo,见'cargo-zhelp'fordetails-h,--helpPrintshelpinformationSomecommoncargocommandsare(seeallcommandswith--list):build,bCompilethecurrentpackagecheck,cAnalyzethecurrentpackageandreporterrors,butdon'tbuildobjectfilescleanRemovethetargetdirectorydoc,dBuildthispackage'sanditsdependencies'documentationnewCreateanewcargopackageinitCreateanewcargopackageinanexistingdirectoryrun,rRunabinaryorexampleofthelocalpackagetest,tRunthetestsbenchRunthebenchmarksupdateUpdatedependencieslistedinCargo.locksearchSearchregistryforcratespublishPackageanduploadthispackagetotheregistryinstallInstallaRustbinary.Defaultlocationis$HOME/.cargo/binuninstallUninstallaRustbinarySee'cargohelp'formoreinformationonaspecificcommand.安装wasm-pack要构建二进制包,需要一个额外工具wasm-pack会帮助我们将代码编译成WebAssembly,构建适合web环境的wasm包。使用以下命令下载安装:cargoinstallwasm-packcompilewasmwasm-pack安装成功后,执行以下命令编译wasm包SECRET=wasm-packbuild--target=web--release换成你的签名盐值第一次构建和编译需要很长时间。需要下载依赖的rust库并编译。请耐心等待。如果速度还是很慢,建议更换国内货源。替换cargo源并在您的cargo文件夹下创建一个新的配置文件。macos下,文件夹地址为~/.cargocd~/.cargotouchconfig然后编辑config文件,添加如下内容:[source.crates-io]registry="https://github.com/rust-lang/crates.io-index"replace-with='ustc'[source.ustc]registry="git://mirrors.ustc.edu.cn/crates.io-index"可以替换成ustc的源码集成,执行wasm-pack命令打包会在项目根目录下获取一个名为pkg的文件夹,放入前端项目中使用,即按照文中介绍的方式集成调用即可上面的代码示例章节。附录rust项目地址:https://github.com/swearer23/ron-weasleyvue3调用示例项目地址:https://github.com/swearer23/harry-porter(可以使用包含secret=123456的wasm包作为示例)