亚马逊SP API加密压缩报告解压报错:incorrect header check 解决方法
问题
我正在使用亚马逊Selling Partner API的getReport操作获取documentId,随后用于下载加密且压缩的报告文档。代码如下:
const documentData = await this.sellingPartner.callAPI({ operation: "getReportDocument", endpoint: "reports", path: { reportDocumentId: reportData.reportDocumentId } }) const request = https.get(documentData.url, function(res) { const data = []; res.on("data", chunk => data.push(chunk)); res.on("end", () => { const key = new Buffer.from(documentData.encryptionDetails.key, 'base64') const initializationVector = new Buffer.from(documentData.encryptionDetails.initializationVector, 'base64') const input = Buffer.concat(data) let result; try { result = aes.decryptText( aes.CIPHERS.AES_256, key, initializationVector, input ) } catch (e) { console.log(e) } console.log(">>>>") console.log(result) zlib.gunzip(result, (err, unzipped) => { debugger }); }); }
当前遇到zlib报错:
Error: incorrect header check at Zlib.zlibOnError [as onerror] (node:zlib:189:17)
即使直接将未加密值传入zlib也会出现相同错误。文档中有Java示例代码,但无法明确其解密是在解压前还是解压后。请问正确的处理顺序是先解压再解密还是先解密再解压?后者看似可行但解压环节失败,该如何解决此解压问题?
解答
正确处理顺序:先解密,再解压
亚马逊SP API返回的报告文档是先通过AES-256加密,再进行gzip压缩的,所以必须先解密得到原始压缩数据,再执行解压操作。解压报错的解决步骤
验证解密逻辑正确性
确认aes.decryptText的实现完全符合SP API要求:- 必须使用AES-256-CBC加密模式(SP API官方指定)
- 填充方式需为
PKCS7Padding(Java示例默认使用该填充,Node.js中对应pkcs7) - 解密后可以打印
result.toString('hex')的前4个字符,验证是否以1f8b开头——这是gzip文件的标准十六进制头标识,若不是则说明解密环节出错。
确保下载数据完整
手动拼接Buffer可能导致数据损坏或截断,建议改用流式处理:const crypto = require('crypto'); const zlib = require('zlib'); const https = require('https'); // 先从documentData获取key和iv const key = Buffer.from(documentData.encryptionDetails.key, 'base64'); const iv = Buffer.from(documentData.encryptionDetails.initializationVector, 'base64'); https.get(documentData.url, (res) => { const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); const gunzip = zlib.createGunzip(); res.pipe(decipher) .pipe(gunzip) .on('data', (chunk) => { // 处理解压后的明文内容 console.log(chunk.toString()); }) .on('error', (err) => { console.error('处理出错:', err); }); });流式处理可以避免内存拼接Buffer的潜在问题,同时实时处理数据,降低内存占用。
调整zlib参数适配特殊gzip格式
如果解密后的数据确实是gzip格式但仍报错,尝试调整windowBits参数:zlib.gunzip(result, { windowBits: zlib.Z_MAX_WBITS }, (err, unzipped) => { if (err) { console.error(err); return; } // 处理解压结果 });部分情况下,gzip数据的头部标识特殊,增大windowBits可以解决解析问题。
内容的提问来源于stack exchange,提问作者Ionică Bizău
相关产品推荐
相关产品推荐

