Wenn Sie Integrationen erstellen, die Webhooks von Zendesk empfangen, öffnen Sie einen Endpunkt auf Ihrem Server, der HTTP-Anfragen aus dem Internet akzeptiert. Ohne ordnungsgemäße Überprüfung könnte jeder gefälschte Anfragen an diesen Endpunkt senden und potenziell unerwünschte Aktionen in Ihrem System auslösen. Hier kommt die Signaturüberprüfung ins Spiel.
Die Zendesk-Webhook-Signaturüberprüfung bietet Ihnen eine Möglichkeit, kryptografisch zu beweisen, dass eingehende Webhooks tatsächlich von Zendesk stammen und während der Übertragung nicht manipuliert wurden. Diese Anleitung führt Sie durch alles, was Sie benötigen, um sie korrekt zu implementieren, mit funktionierenden Codebeispielen in fünf gängigen Programmiersprachen.
Wenn Sie eine umfassendere Anleitung zum Einrichten von Webhooks in Zendesk suchen, behandelt unsere Zendesk Messaging Webhooks Setup Anleitung den vollständigen Konfigurationsprozess.

Was ist Webhook-Signaturüberprüfung und warum ist sie wichtig
Die Webhook-Signaturüberprüfung ist ein Sicherheitsmechanismus, mit dem Sie die Authentizität eingehender Webhook-Anfragen bestätigen können. Wenn Zendesk einen Webhook an Ihren Endpunkt sendet, enthält er eine kryptografische Signatur, die nur von Zendesk generiert werden konnte. Ihr Server berechnet diese Signatur mithilfe eines gemeinsamen Geheimnisses neu und vergleicht die Ergebnisse. Wenn sie übereinstimmen, ist der Webhook echt.
Ohne diese Überprüfung ist Ihr Endpunkt anfällig für verschiedene Angriffe:
- Spoofing (Fälschung): Jeder, der Ihre Webhook-URL entdeckt, könnte gefälschte Anfragen senden, die vorgeben, von Zendesk zu stammen
- Replay-Angriffe: Ein Angreifer könnte einen legitimen Webhook abfangen und ihn mehrmals erneut senden
- Payload-Manipulation: Anforderungsdaten könnten während der Übertragung unbemerkt verändert werden
Für Produktionsintegrationen, die sensible Ticketdaten verarbeiten oder automatisierte Workflows auslösen, ist die Signaturüberprüfung nicht optional. Sie ist eine grundlegende Sicherheitskontrolle, die sowohl Ihr System als auch die Daten Ihrer Kunden schützt.
Bei eesel AI handhaben wir die Webhook-Sicherheit automatisch, wenn Sie Ihr Zendesk-Konto verbinden. Unsere Plattform überprüft Signaturen transparent, sodass Sie sich auf den Aufbau von Automatisierungen konzentrieren können, anstatt auf kryptografische Implementierungen.
Wie Zendesk-Webhook-Signaturen funktionieren
Zendesk verwendet den SHA256 HMAC (Hash-based Message Authentication Code)-Algorithmus, um Webhook-Signaturen zu generieren. Der Prozess kombiniert das Signierungsgeheimnis Ihres Webhooks mit der Anforderungs-Payload und dem Zeitstempel, um eine eindeutige Signatur für jede Anforderung zu erstellen.
Die Formel sieht wie folgt aus:
base64(HMACSHA256(TIMESTAMP + BODY))
Folgendes passiert, wenn Zendesk einen Webhook sendet:
- Zendesk verkettet den Zeitstempel und den rohen Anforderungstext zu einer einzigen Zeichenkette (String)
- Es erstellt einen HMAC-SHA256-Hash unter Verwendung des Signierungsgeheimnisses Ihres Webhooks als Schlüssel
- Der Hash wird Base64-codiert, um die endgültige Signatur zu erzeugen
- Zendesk sendet den Webhook mit zwei kritischen Headern:
X-Zendesk-Webhook-Signature- die generierte SignaturX-Zendesk-Webhook-Signature-Timestamp- der im Signatur verwendete Zeitstempel
Jede Webhook-Anfrage von Zendesk enthält diese Standard-Header:
x-zendesk-account-id: 123456
x-zendesk-webhook-id: 01F1KRFQ6BG29CNWFR60NK5FNY
x-zendesk-webhook-invocation-id: 8350205582
x-zendesk-webhook-signature: EiqWE3SXTPQpPulBV6OSuuGziIishZNc1VwNZYqZrHU=
x-zendesk-webhook-signature-timestamp: 2021-03-25T05:09:27Z
Auf Ihrem Server extrahieren Sie diese Header, berechnen die Signatur mithilfe Ihres gespeicherten Signierungsgeheimnisses neu und vergleichen die Ergebnisse. Wenn die Signaturen übereinstimmen, können Sie darauf vertrauen, dass der Webhook von Zendesk stammt und die Payload nicht verändert wurde.
Abrufen Ihres Webhook-Signierungsgeheimnisses
Bevor Sie Signaturen überprüfen können, benötigen Sie das Signierungsgeheimnis für Ihren Webhook. Jeder Webhook in Zendesk hat sein eigenes eindeutiges Geheimnis, das bei der Erstellung des Webhooks generiert wird.
Finden Ihres Geheimnisses im Admin Center
- Navigieren Sie zum Zendesk Admin Center (Admin Center > Apps und Integrationen > Webhooks)
- Wählen Sie den Webhook aus, den Sie überprüfen möchten
- Suchen Sie auf der Seite mit den Webhook-Details nach dem Feld für das Signierungsgeheimnis
- Klicken Sie auf "Geheimnis anzeigen", um den Wert anzuzeigen

Behandeln Sie dieses Geheimnis wie jede andere Anmeldeinformation. Übertragen Sie es nicht in Code, geben Sie es nicht in clientseitigen Anwendungen preis und beschränken Sie den Zugriff darauf innerhalb Ihres Teams.
Abrufen über API
Sie können das Signierungsgeheimnis auch programmgesteuert mithilfe der Show Webhook Signing Secret API abrufen:
GET /api/v2/webhooks/{webhook_id}/signing_secret
Statisches Testgeheimnis für die Entwicklung
Wenn Sie Webhooks testen, bevor Sie sie in Zendesk erstellen, benötigen Sie ein statisches Signierungsgeheimnis, da tatsächliche Geheimnisse erst nach der Webhook-Erstellung generiert werden. Verwenden Sie dieses Testgeheimnis während der Entwicklung:
dGhpc19zZWNyZXRfaXNfZm9yX3Rlc3Rpbmdfb25seQ==
Sobald Ihr Webhook erstellt wurde, wechseln Sie zum tatsächlichen Signierungsgeheimnis. Test-Webhooks und Live-Webhooks verwenden unterschiedliche Geheimnisse, daher muss Ihr Überprüfungscode das richtige Geheimnis für jede Umgebung verarbeiten.

Schritt-für-Schritt-Implementierungsanleitung
Die Implementierung der Signaturüberprüfung umfasst vier wichtige Schritte. Lassen Sie uns jeden einzelnen aufschlüsseln.
Schritt 1: Erfassen Sie den rohen Anforderungstext
Die Signatur wird auf dem rohen Anforderungstext als Zeichenkette (String) berechnet, nicht auf geparstem JSON oder Formulardaten. Wenn Ihr Framework den Text analysiert, bevor Sie darauf zugreifen können, schlägt die Signaturüberprüfung fehl, da die rohen Bytes transformiert wurden.
Die meisten Web-Frameworks bieten Middleware oder Konfigurationsoptionen, um den rohen Text vor dem Parsen zu erfassen. Normalerweise müssen Sie den rohen Text in einer Eigenschaft wie req.rawBody speichern, damit er für die Signaturberechnung verfügbar ist.
Häufige Fehlerquelle: Body-Parsing-Middleware (wie express.json() von Express) wird oft vor Ihrem Routen-Handler ausgeführt. Wenn der Text in ein JavaScript-Objekt geparst wird, bevor Sie die rohe Zeichenkette (String) erfassen, können Sie die ursprünglichen Bytes für die Signaturüberprüfung nicht wiederherstellen. Konfigurieren Sie Ihre Middleware so, dass sie zuerst den rohen Text erfasst.
Schritt 2: Extrahieren Sie Signatur-Header
Ziehen Sie die beiden signaturbezogenen Header aus der eingehenden Anfrage:
X-Zendesk-Webhook-Signature- die Signatur, gegen die geprüft werden sollX-Zendesk-Webhook-Signature-Timestamp- der Zeitstempel, der bei der Signaturberechnung verwendet wurde
Beachten Sie, dass einige Frameworks Header-Namen transformieren. In Ruby on Rails wird beispielsweise der Header X-Zendesk-Webhook-Signature in der Anfrageumgebung zu HTTP_X_ZENDESK_WEBHOOK_SIGNATURE.
Schritt 3: Berechnen Sie die erwartete Signatur
Verketten Sie den Zeitstempel und den rohen Text und erstellen Sie dann einen HMAC-SHA256-Hash unter Verwendung Ihres Signierungsgeheimnisses:
- Erstellen Sie eine Zeichenkette (String):
timestamp + body(zuerst der Zeitstempel, dann der rohe Text) - Generieren Sie HMAC-SHA256 unter Verwendung Ihres Signierungsgeheimnisses als Schlüssel
- Base64-codieren Sie den resultierenden Hash
Diese berechnete Signatur sollte mit der übereinstimmen, die Zendesk im Header X-Zendesk-Webhook-Signature gesendet hat.
Schritt 4: Vergleichen Sie Signaturen sicher
Verwenden Sie eine Vergleichsfunktion mit konstanter Zeit, um die Signaturen zu vergleichen. Ein regulärer Zeichenkettenvergleich (== oder ===) kann Informationen über die Signatur durch Zeitanalyse preisgeben, was einem Angreifer theoretisch helfen könnte, gültige Signaturen zu fälschen.
Die meisten Sprachen bieten eine Vergleichsfunktion mit konstanter Zeit:
- Node.js:
crypto.timingSafeEqual() - Python:
hmac.compare_digest() - PHP:
hash_equals() - Ruby:
ActiveSupport::SecurityUtils.secure_compare() - C#: Kein integrierter Vergleich mit konstanter Zeit, aber
CryptographicOperations.FixedTimeEquals()in .NET Core
Wenn die Signaturen übereinstimmen, verarbeiten Sie den Webhook. Wenn sie nicht übereinstimmen, geben Sie eine 401 Unauthorized-Antwort zurück und protokollieren Sie den Fehler zur Untersuchung.
Codebeispiele in gängigen Sprachen
Hier sind vollständige, funktionierende Implementierungen für die gängigsten Webentwicklungssprachen.
Node.js/Express
const express = require('express');
const crypto = require('crypto');
const SIGNING_SECRET = 'your_webhook_signing_secret_here';
const PORT = 3000;
const app = express();
// Middleware zum Erfassen des rohen Texts
function storeRawBody(req, res, buf) {
if (buf && buf.length) {
req.rawBody = buf.toString('utf8');
}
}
app.use(express.json({ verify: storeRawBody }));
app.use(express.urlencoded({ verify: storeRawBody, extended: true }));
function isValidSignature(signature, body, timestamp) {
const hmac = crypto.createHmac('sha256', SIGNING_SECRET);
const sig = hmac.update(timestamp + body).digest('base64');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(sig)
);
}
app.post('/webhook', (req, res) => {
const signature = req.headers['x-zendesk-webhook-signature'];
const timestamp = req.headers['x-zendesk-webhook-signature-timestamp'];
const body = req.rawBody;
if (!isValidSignature(signature, body, timestamp)) {
console.log('Invalid webhook signature');
return res.status(401).send('Unauthorized');
}
// Verarbeiten Sie den verifizierten Webhook
console.log('Webhook verified, processing...');
res.status(200).send('OK');
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Python (Flask)
from flask import Flask, request, abort
import hmac
import hashlib
import base64
app = Flask(__name__)
SIGNING_SECRET = b'your_webhook_signing_secret_here'
@app.route('/webhook', methods=['POST'])
def handle_webhook():
# Get raw body
raw_body = request.get_data()
# Extract headers
signature = request.headers.get('X-Zendesk-Webhook-Signature', '')
timestamp = request.headers.get('X-Zendesk-Webhook-Signature-Timestamp', '')
# Calculate expected signature
signed_payload = (timestamp + raw_body.decode('utf-8')).encode('utf-8')
expected_signature = base64.b64encode(
hmac.new(SIGNING_SECRET, signed_payload, hashlib.sha256).digest()
).decode('utf-8')
# Verify signature
if not hmac.compare_digest(expected_signature, signature):
abort(401)
# Process verified webhook
return '', 200
if __name__ == '__main__':
app.run(port=3000)
PHP
<?php
define('SIGNING_SECRET', 'your_webhook_signing_secret_here');
function verify_webhook($body, $signature, $timestamp) {
// Concatenate timestamp and body
$signed_payload = $timestamp . $body;
// Calculate HMAC (binary output)
$calculated_hmac = base64_encode(
hash_hmac('sha256', $signed_payload, SIGNING_SECRET, true)
);
// Constant-time comparison
return hash_equals($signature, $calculated_hmac);
}
// Handle webhook request
$signature = $_SERVER['HTTP_X_ZENDESK_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_ZENDESK_WEBHOOK_SIGNATURE_TIMESTAMP'] ?? '';
$body = file_get_contents('php://input');
if (!verify_webhook($body, $signature, $timestamp)) {
http_response_code(401);
exit('Unauthorized');
}
// Process verified webhook
http_response_code(200);
echo 'OK';
Ruby on Rails
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
SIGNING_SECRET = ENV['ZENDESK_WEBHOOK_SECRET']
def zendesk
signature = request.headers['HTTP_X_ZENDESK_WEBHOOK_SIGNATURE']
timestamp = request.headers['HTTP_X_ZENDESK_WEBHOOK_SIGNATURE_TIMESTAMP']
body = request.body.read
# Calculate signature
signed_payload = timestamp + body
expected_signature = Base64.strict_encode64(
OpenSSL::HMAC.digest('SHA256', SIGNING_SECRET, signed_payload)
)
# Verify
unless ActiveSupport::SecurityUtils.secure_compare(expected_signature, signature)
head :unauthorized
return
end
# Process webhook
head :ok
end
end
C#
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("webhook")]
public class WebhookController : ControllerBase
{
private const string SigningSecret = "your_webhook_signing_secret_here";
[HttpPost]
public IActionResult HandleWebhook()
{
string signature = Request.Headers["X-Zendesk-Webhook-Signature"];
string timestamp = Request.Headers["X-Zendesk-Webhook-Signature-Timestamp"];
// Read raw body
using var reader = new StreamReader(Request.Body);
string body = reader.ReadToEnd();
// Calculate signature
string signedPayload = timestamp + body;
byte[] keyBytes = Encoding.UTF8.GetBytes(SigningSecret);
byte[] payloadBytes = Encoding.UTF8.GetBytes(signedPayload);
using var hmac = new HMACSHA256(keyBytes);
byte[] hash = hmac.ComputeHash(payloadBytes);
string expectedSignature = Convert.ToBase64String(hash);
// Compare (case-insensitive for compatibility)
if (!signature.Equals(expectedSignature, StringComparison.OrdinalIgnoreCase))
{
return Unauthorized();
}
return Ok();
}
}
Häufige Probleme und Fehlerbehebung
Auch mit dem richtigen Code kann die Signaturüberprüfung aus subtilen Gründen fehlschlagen. Hier sind die häufigsten Probleme, auf die Entwickler stoßen.
JSON-Abstand und -Formatierung
Eines der frustrierendsten Probleme betrifft die JSON-Formatierung. Die Signatur wird auf den exakten Bytes berechnet, die Zendesk sendet, einschließlich Leerzeichen. Wenn Ihr Framework das JSON neu formatiert (Hinzufügen oder Entfernen von Leerzeichen), stimmt die Signatur nicht überein.
Ein Entwickler in der Zendesk-Community hat dies auf die harte Tour entdeckt:
Die Lösung besteht darin, die Signatur immer anhand des rohen Anforderungstexts zu überprüfen, bevor eine Analyse oder Transformation erfolgt.
Unterschiede zwischen Test-Webhook und Live-Webhook
Ein weiteres häufiges Problem betrifft Unterschiede zwischen der Test-Webhook-Funktion von Zendesk und Live-Webhook-Aufrufen. Das Payload-Format kann zwischen den beiden leicht variieren, was dazu führt, dass Signaturen bei Tests validiert werden, aber in der Produktion fehlschlagen.
Testen Sie immer mit tatsächlichen Webhook-Aufrufen von echten Zendesk-Ereignissen, bevor Sie in der Produktion bereitstellen.
Zeichencodierung
Stellen Sie sicher, dass sowohl der Zeitstempel als auch der Text als UTF-8-Zeichenketten (Strings) behandelt werden, wenn sie zur Signaturberechnung verkettet werden. Codierungsfehler zwischen Ihrem Server und der Payload von Zendesk führen zu Überprüfungsfehlern.
Zeitstempelvalidierung
Erwägen Sie, eine Zeitstempelvalidierung hinzuzufügen, um Replay-Angriffe zu verhindern. Überprüfen Sie, ob der Zeitstempel im Header innerhalb eines angemessenen Zeitfensters (z. B. 5 Minuten) der aktuellen Zeit liegt. Alte Zeitstempel könnten auf einen Replay-Angriff hindeuten.
Wann Geheimnisse neu generiert werden müssen
Wenn Sie vermuten, dass Ihr Signierungsgeheimnis kompromittiert wurde, generieren Sie es sofort über das Zendesk Admin Center neu. Aktualisieren Sie nach der Neugenerierung Ihren Server mit dem neuen Geheimnis. Es kann ein kurzes Zeitfenster geben, in dem Webhooks während der Übertragung das alte Geheimnis verwenden, daher sollten Sie in Erwägung ziehen, beide während des Übergangs zu unterstützen.
Testen Ihrer Webhook-Überprüfung
Testen Sie Ihre Signaturüberprüfungs-Implementierung gründlich, bevor Sie sie in der Produktion bereitstellen.
Verwenden des statischen Testgeheimnisses
Verwenden Sie während der Entwicklung das statische Testgeheimnis von Zendesk (dGhpc19zZWNyZXRfaXNfZm9yX3Rlc3Rpbmdfb25seQ==), um zu überprüfen, ob Ihre Implementierungslogik korrekt ist. Auf diese Weise können Sie testen, ohne einen Live-Webhook zu erstellen.
Testen mit der Testfunktion von Zendesk
Wenn Sie einen Webhook in Zendesk erstellen oder bearbeiten, verwenden Sie die Schaltfläche "Webhook testen", um Test-Payloads zu senden. Überprüfen Sie, ob Ihr Endpunkt diese Anfragen akzeptiert und die Signatur korrekt validiert.
Live-Tests
Erstellen Sie einen echten Auslöser, der Ihren Webhook bei einem bestimmten Ereignis (z. B. einer Ticket-Erstellung) aufruft. Führen Sie diese Aktion in Zendesk aus und bestätigen Sie, dass Ihr Endpunkt den Webhook empfängt und verifiziert. Überprüfen Sie Ihre Serverprotokolle auf Signaturabweichungen.
Protokollierung und Debugging
Protokollieren Sie die folgenden Informationen während der Entwicklung, um Fehler zu beheben:
- Roher Anforderungstext (vor dem Parsen)
- Empfangener Signatur-Header
- Berechnete Signatur
- Zeitstempel-Header
Protokollieren Sie niemals das Signierungsgeheimnis selbst. Vergleichen Sie die empfangenen und berechneten Signaturen Zeichen für Zeichen, um festzustellen, wo sie sich unterscheiden.
Sichern Sie Ihre Zendesk-Integrationen mit eesel AI
Die korrekte Implementierung der Webhook-Signaturüberprüfung erfordert sorgfältige Beachtung kryptografischer Details, frameworkspezifischer Textverarbeitung und Sonderfälle bei der JSON-Formatierung. Für Teams, die komplexe Integrationen erstellen, kann diese Komplexität die Entwicklung verlangsamen und Sicherheitsrisiken bergen.
Bei eesel AI haben wir die Webhook-Sicherheit direkt in unsere Zendesk-Integration integriert. Wenn Sie Ihr Zendesk-Konto mit unserer Plattform verbinden, übernehmen wir die Signaturüberprüfung automatisch. Sie erhalten die Sicherheitsvorteile, ohne Überprüfungscode schreiben und pflegen zu müssen.

Unser KI-Agent für Zendesk geht noch weiter und bietet eine autonome Ticketlösung, während er die gesamte Webhook-Sicherheit im Hintergrund abwickelt. Wenn Sie Webhook-basierte Automatisierungen erstellen und sich auf die Geschäftslogik anstatt auf kryptografische Implementierungen konzentrieren möchten, können wir Ihnen helfen, Ihre Integration zu vereinfachen.
Häufig gestellte Fragen
Diesen Beitrag teilen

Article by
Stevia Putri
Stevia Putri is a marketing generalist at eesel AI, where she helps turn powerful AI tools into stories that resonate. She’s driven by curiosity, clarity, and the human side of technology.



