Node.js与Flutter使用crypto包生成SHA256结果不一致问题咨询
问题根因
- 核心差异来自不同平台下JSON序列化对浮点数的处理规则不一致:
- Flutter Web编译为JavaScript目标,
json.encode本质调用JS的JSON.stringify,对于值为整数的浮点数(如3700.0)会自动序列化为无小数点的整数形式3700,和Node.js端默认JSON.stringify逻辑完全一致,所以哈希结果相同。 - Flutter Android端运行在Dart VM中,默认
json.encode会保留浮点数的小数点标识,将3700.0序列化为3700.0,导致最终拼接的待哈希字符串和Node.js端存在差异,哈希结果自然不同。
- Flutter Web编译为JavaScript目标,
- 次要排查点:需确认两边JSON序列化的键顺序、多余空格/换行、尾逗号规则完全一致,默认情况下两边无多余格式化空格,不会导致差异。
解决方案
- 统一数值类型:避免使用无必要的浮点数类型,将明确为整数的字段统一改为整数类型。示例中把
invoiceAmount的值从3700.0改为3700,即可消除浮点数序列化差异。 - 对齐序列化规则:如果必须使用浮点数,自定义两边的序列化逻辑,对浮点数值统一格式输出,例如保留固定小数位、或转成字符串后再序列化。
- 前置校验:执行哈希前先打印两边拼接后的完整待哈希字符串,直接对比内容是否完全一致,可快速定位差异点。
修正后Dart代码
import 'dart:convert'; import 'package:crypto/crypto.dart'; void main() { final mapData = { "invoiceAmount": 3700, // 改为整数类型 "notes": { "env": "np", } }; final serializedStr = "abc-234-abc" + json.encode(mapData); // 可打印serializedStr和Node端结果做对比 final bytes = utf8.encode(serializedStr); final digest = sha256.convert(bytes); print(digest); }
修正后Node.js代码
const crypto = require('crypto') const mapData = { "invoiceAmount": 3700, // 对应改为整数类型 "notes": { "env": "np", } } const serializedStr = "abc-234-abc" + JSON.stringify(mapData) const hash = crypto.createHash('sha256').update(serializedStr).digest('hex') console.log(hash)
内容的提问来源于stack exchange,提问作者Shivang Gupta
相关产品推荐
相关产品推荐

