ExpressJS octet-stream SHA256校验和与openssl/sha256sum不匹配问题
问题:Node.js Crypto生成的SHA256摘要与sha256sum不一致
问题描述
配置了如下ExpressJS请求处理器:
//app.ts: app.use(express.json()); app.use(express.raw()); app.use(express.urlencoded({ extended: false })); app.use(routeHandler); // routeHandler.ts: (req: Request, res: Response) => { const {digest} = req.query; freshDigest = crypto.createHash('sha256').update(req.body).digest('hex'); if(digest !== freshDigest) throw ValidationError('digest mismatch'); }
随后使用以下curl命令上传application/octet-stream类型文件:
curl -H'Content-Type: application/octet-stream' -XPOST \ -v \ "localhost:port/v2/path/to/route/?digest=sha256:$(sha256sum /path/to.file.html|cut -d' ' -f1)" \ -d@/path/to.file.html.html \ -H'Authorization: Bearer REDACTED'
文件支持任意类型(压缩包、文本等),仅需上传原始字节流,但Node.js crypto生成的摘要与sha256sum/openssl dgst -sha256结果不一致,存在以下使用错误:
错误分析与修复方案
1. Curl上传参数错误
使用-d@参数时,curl会默认将请求视为application/x-www-form-urlencoded类型,自动对文件内容进行URL编码(比如转义特殊字符、处理换行符),导致上传的字节流与原文件不一致。
修复:替换-d@为--data-binary@,确保文件字节流原样上传:
curl -H'Content-Type: application/octet-stream' -XPOST \ -v \ "localhost:port/v2/path/to/route/?digest=$(sha256sum /path/to.file.html|cut -d' ' -f1)" \ --data-binary@/path/to.file.html \ -H'Authorization: Bearer REDACTED'
2. 摘要参数格式不匹配
curl命令中生成的digest参数带sha256:前缀(如sha256:abc123...),但代码中直接将其与纯十六进制格式的freshDigest对比,格式不统一导致校验失败。
修复(二选一):
- 方案1:修改curl命令,去掉
sha256:前缀(如上例所示) - 方案2:修改代码,提取摘要的十六进制部分:
// routeHandler.ts: (req: Request, res: Response) => { const { digest } = req.query; const expectedDigest = typeof digest === 'string' ? digest.replace(/^sha256:/, '') : ''; const freshDigest = crypto.createHash('sha256').update(req.body).digest('hex'); if(expectedDigest !== freshDigest) throw ValidationError('digest mismatch'); }
3. Express中间件顺序隐患(可选优化)
虽然express.json()和express.urlencoded()默认只处理对应Content-Type的请求,但将express.raw()放在最前面可避免其他中间件意外干扰原始字节流的解析:
//app.ts: app.use(express.raw({ type: 'application/octet-stream' })); // 显式指定处理类型 app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(routeHandler);
内容的提问来源于stack exchange,提问作者Yarden Bar
相关产品推荐
相关产品推荐

