保护 Webhook 安全
保护 Webhook 安全
Section titled “保护 Webhook 安全”为确保 Webhook 的真实性和完整性,我们提供了一个可供验证的 X-Signature header。该 header 包含使用你的 personal_secret 生成的签名,你可以通过验证它来确认该 Webhook 请求是合法的、未被篡改的。
- 设置 Personal Secret:如果你尚未设置 personal secret,请注意,添加一个 personal secret 会为所有发出的 Webhook 启用
X-Signatureheader。请确保你的服务器能够接受并验证该 header。 - 更新你的 Personal Secret:如果你已经有一个 personal secret 并选择更改它,新的 secret 将立即对 Webhook 通知生效。请确保你的服务器已更新为使用新的 secret,以避免任何中断。
设置 Personal Secret
Section titled “设置 Personal Secret”你可以在我们平台上的个人资料设置中设置或重新生成你的 personal secret。请按照以下步骤操作:
- 前往个人资料设置:个人资料设置
- 找到 Personal Secret 部分:找到标记为”Personal Secret”的部分。
- 设置或重新生成 secret:
- 如果尚未设置 secret,点击”Set Personal Secret”以生成一个新的 secret。
- 如果已经存在 secret,点击”Regenerate Secret”以创建一个新的。
X-Signature Header 是如何构建的
Section titled “X-Signature Header 是如何构建的”从 Payload 中提取 txid:
txid(交易 ID)是 Webhook payload 中包含的唯一标识符。此 ID 被用作签名生成过程的一部分。 将 txid 与 Personal Secret 结合:
personal secret 是仅发送方(例如 Webhook 提供方)和接收方(你的应用程序)知晓的共享密钥。此密钥确保签名只能由知晓该密钥的各方生成和验证。 生成 HMAC(Hash-based Message Authentication Code):
HMAC 是一种特定类型的消息认证码(MAC),涉及加密哈希函数和一个密钥。在这种情况下,txid 和 personal secret 被用于生成 HMAC。 HMAC 通常使用像 SHA-256 这样的哈希算法生成。
验证 X-Signature Header
Section titled “验证 X-Signature Header”当你收到一个 Webhook 时,验证 X-Signature header 以确保该请求来自受信任的来源至关重要。以下是在 Python、Java、PHP 和 JavaScript 中执行此验证的示例。
import hmacimport hashlibimport base64
def verify_signature(txid, received_signature, personal_secret): # Generate the expected signature expected_signature = base64.b64encode(hmac.new( personal_secret.encode(), txid.encode(), hashlib.sha256 ).digest()).decode()
# Compare the expected signature with the received signature return hmac.compare_digest(expected_signature, received_signature)
# Example usagetxid = 'your_txid_here'received_signature = 'received_signature_here'personal_secret = 'your_personal_secret_here'
if verify_signature(txid, received_signature, personal_secret): print("Signature is valid.")else: print("Invalid signature.")import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;
public class SignatureVerifier { public static boolean verifySignature(String txid, String receivedSignature, String personalSecret) throws Exception { Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(personalSecret.getBytes(), "HmacSHA256"); mac.init(secretKeySpec);
byte[] signatureBytes = mac.doFinal(txid.getBytes()); String expectedSignature = Base64.getEncoder().encodeToString(signatureBytes);
return expectedSignature.equals(receivedSignature); }
public static void main(String[] args) { try { String txid = "your_txid_here"; String receivedSignature = "received_signature_here"; String personalSecret = "your_personal_secret_here";
if (verifySignature(txid, receivedSignature, personalSecret)) { System.out.println("Signature is valid."); } else { System.out.println("Invalid signature."); } } catch (Exception e) { e.printStackTrace(); } }}function verifySignature($txid, $receivedSignature, $personalSecret) { // Generate the expected signature $expectedSignature = base64_encode(hash_hmac('sha256', $txid, $personalSecret, true));
// Compare the expected signature with the received signature return hash_equals($expectedSignature, $receivedSignature);}
// Example usage$txid = 'your_txid_here';$receivedSignature = 'received_signature_here';$personalSecret = 'your_personal_secret_here';
if (verifySignature($txid, $receivedSignature, $personalSecret)) { echo "Signature is valid.";} else { echo "Invalid signature.";}const crypto = require('crypto');
function verifySignature(txid, receivedSignature, personalSecret) { // Generate the expected signature const expectedSignature = crypto .createHmac('sha256', personalSecret) .update(txid) .digest('base64');
// Compare the expected signature with the received signature return crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(receivedSignature));}
// Example usageconst txid = 'your_txid_here';const receivedSignature = 'received_signature_here';const personalSecret = 'your_personal_secret_here';
if (verifySignature(txid, receivedSignature, personalSecret)) { console.log("Signature is valid.");} else { console.log("Invalid signature.");}借助管理你的 personal_secret 的能力,你能更好地掌控 Webhook 的安全性。每当你更改 personal_secret 时,请务必确保服务器的 Webhook 处理程序已更新,以防止服务中断。如果你有任何问题或遇到问题,请联系支持团队。