
本文旨在解决在Webhook签名验证过程中,Python与TypeScript实现之间出现的差异问题。通过详细分析两种语言在JSON序列化时的不同行为,提供了一套可靠的TypeScript解决方案,确保签名验证的一致性和准确性。该方案通过规范化JSON字符串格式,消除了因空格差异导致的验证失败问题,从而保证了Webhook通信的安全性和可靠性。
在开发涉及Webhook的应用时,确保接收到的数据确实来自可信来源至关重要。Webhook签名验证是一种常见的安全措施,它通过使用共享密钥对请求内容进行签名,并在接收端验证签名,从而防止恶意篡改。然而,在跨语言环境中实现签名验证时,可能会遇到一些意想不到的问题,例如Python和TypeScript在处理JSON序列化时的差异。
Python的json.dumps()方法在默认情况下会生成紧凑的JSON字符串,不包含额外的空格。而TypeScript中使用JSON.stringify()在没有指定参数的情况下也会生成紧凑的JSON字符串。但是,如果格式化JSON(例如为了方便调试),可能会引入空格,导致生成的签名与预期不符。即使没有格式化,不同的JSON序列化库也可能在空格处理上存在细微差异。
为了解决这个问题,我们需要在TypeScript中规范化JSON字符串的格式,使其与Python生成的格式保持一致。一种有效的方法是使用一系列的字符串替换操作,移除或调整JSON字符串中的空格。
立即学习“Python免费学习笔记(深入)”;
以下代码展示了如何使用Ramda库中的pipe和replace函数,创建一个名为toJSONWithSpaces的函数,该函数可以规范化JSON字符串的格式:
import { pipe, replace } from 'ramda';
export const toJSONWithSpaces = pipe(
(object: unknown) => JSON.stringify(object, null, 1), // stringify with line-breaks and indents
replace(/\n +/gm, ' '), // replace line breaks and following spaces with a single space
replace(/:\s/g, ': '), // ensure a space after colon
replace(/{\s/g, '{'), // remove space after opening brace
replace(/\s}/g, '}'), // remove space before closing brace
replace(/\[\s/g, '['), // remove space after opening bracket
replace(/\s]/g, ']'), // remove space before closing bracket
replace(/,\s/g, ', '), // ensure a space after comma
);这个函数首先使用JSON.stringify(object, null, 1)将对象转换为带有换行符和缩进的JSON字符串。然后,它使用一系列的正则表达式替换操作来移除或调整空格,以确保JSON字符串的格式与Python生成的格式一致。
接下来,我们需要将toJSONWithSpaces函数集成到签名验证函数中。以下是一个修改后的verifyCloseSignature函数,它使用toJSONWithSpaces函数来规范化payload:
import { toJSONWithSpaces } from './json-formatter'; // 假设 toJSONWithSpaces 函数在 json-formatter.ts 文件中
import * as crypto from 'crypto';
export function verifyCloseSignature(
request: Request,
key: string,
payload: any,
) {
const headers = request.headers;
const timestamp = headers.get('close-sig-timestamp');
const providedSignature = headers.get('close-sig-hash');
if (!timestamp) {
throw new Error('[verifyCloseSignature] Required timestamp header missing');
}
if (!providedSignature) {
throw new Error('[verifyCloseSignature] Required signature header missing');
}
const hmac = crypto.createHmac('sha256', Buffer.from(key, 'hex'));
const cleanedPayload = toJSONWithSpaces(payload);
hmac.update(timestamp + cleanedPayload);
const calculatedSignature = hmac.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(providedSignature, 'hex'),
Buffer.from(calculatedSignature, 'hex'),
);
}在这个修改后的函数中,我们首先使用toJSONWithSpaces(payload)来规范化payload,然后再将其用于HMAC计算。
通过规范化JSON字符串的格式,我们可以解决在Webhook签名验证过程中Python和TypeScript实现之间的差异问题。这种方法可以确保签名验证的一致性和准确性,从而提高Webhook通信的安全性和可靠性。在实际应用中,建议编写单元测试来验证签名验证函数的正确性,并定期审查和更新代码,以应对潜在的安全风险。
以上就是解决Webhook签名验证中Python与TypeScript差异的实用指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号