You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:25