Zum Inhalt

Verschlüsselung

SecPaid verschlüsselt optional Webhook-Payloads die an Ihren payment_endpoint gesendet werden. Wenn aktiviert, wird das JSON-Payload mit AES-256-CBC vor der Zustellung verschlüsselt.

Verschlüsselung aktivieren

Die Verschlüsselung wird über zwei SecPaid-Attribute Ihres Kontos gesteuert:

Attribut Wert Beschreibung
is_encryption Yes / No Payload-Verschlüsselung ein-/ausschalten
EncryptionKey 32-Zeichen-String Ihr AES-256 Verschlüsselungsschlüssel

Kontaktieren Sie den SecPaid-Support um Verschlüsselung zu aktivieren und Ihren Schlüssel zu setzen, oder verwenden Sie die updateSecPaidAttribute-API.

Auto-generierter Schlüssel

Wenn Sie attributeName: "EncryptionKey" ohne Wert über die API setzen, generiert SecPaid automatisch einen sicheren Schlüssel für Sie.

So funktioniert es

Wenn Verschlüsselung aktiviert ist, ändert sich die Webhook-Zustellung:

Ohne Verschlüsselung:

{
  "ResponseCode": 1,
  "data": {
    "pay_id": 12345,
    "note": "Rechnung #1234",
    "amount": 49.99,
    "user_id": "abc-123",
    "status": "Success"
  }
}

Mit Verschlüsselung:

{
  "data": "U2FsdGVkX1+abc123...base64_verschluesseltes_payload..."
}

Verschlüsselungsprozess

SecPaid führt diese Schritte aus:

  1. Das vollständige Payload-Objekt zu JSON serialisieren
  2. Verschlüsseln mit AES-256-CBC:
    • Key: Ihr 32-Zeichen EncryptionKey
    • IV (Initialisierungsvektor): Erste 16 Zeichen Ihres EncryptionKey
  3. Die verschlüsselten Bytes Base64-kodieren
  4. Als {"data": "<base64_string>"} senden

Entschlüsselung

PHP

function decryptSecPaidWebhook(string $encryptedData, string $encryptionKey): array
{
    $decrypted = openssl_decrypt(
        $encryptedData,
        'AES-256-CBC',
        $encryptionKey,
        0,
        substr($encryptionKey, 0, 16)  // IV = erste 16 Zeichen des Keys
    );

    return json_decode($decrypted, true);
}

// Verwendung im Webhook-Handler:
$payload = $request->all();

if (isset($payload['data']) && is_string($payload['data'])) {
    $payload = decryptSecPaidWebhook(
        $payload['data'],
        env('SECPAID_ENCRYPTION_KEY')
    );
}

JavaScript (Node.js)

const crypto = require('crypto');

function decryptSecPaidWebhook(encryptedData, encryptionKey) {
  const iv = encryptionKey.substring(0, 16);
  const decipher = crypto.createDecipheriv(
    'aes-256-cbc',
    encryptionKey,
    iv
  );

  let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
  decrypted += decipher.final('utf8');

  return JSON.parse(decrypted);
}

Python

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64, json

def decrypt_secpaid_webhook(encrypted_data: str, encryption_key: str) -> dict:
    key = encryption_key.encode('utf-8')
    iv = key[:16]

    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(
        cipher.decrypt(base64.b64decode(encrypted_data)),
        AES.block_size
    )

    return json.loads(decrypted.decode('utf-8'))

Sicherheitshinweise

  • Speichern Sie Ihren EncryptionKey sicher (Umgebungsvariablen, Secrets Manager)
  • Der IV wird vom Key abgeleitet (erste 16 Zeichen) — ein bewusster Trade-off für Einfachheit
  • Rotieren Sie Ihren Schlüssel regelmäßig durch Aktualisierung des EncryptionKey-Attributs
  • Validieren Sie immer die entschlüsselte Payload-Struktur vor der Verarbeitung
  • Wenn die Entschlüsselung fehlschlägt, loggen Sie den Fehler — verarbeiten Sie nicht die rohen verschlüsselten Daten

Testen

In der Entwicklungsumgebung funktioniert die Verschlüsselung identisch zur Produktion. Testen Sie Ihre Entschlüsselungslogik mit Testzahlungen bevor Sie live gehen.