Aller au contenu

Chiffrement de bout en bout

PushGo E2EE protège les domaines d’activité sensibles. L’expéditeur chiffre les champs dans ciphertext, le Gateway relaie ce texte chiffré et les clients déchiffrent localement après la configuration d’une clé.

ContenuProtégé par E2EERemarques
Domaines d’activité à l’intérieur de ciphertextOuiLe Gateway ne peut pas lire le texte en clair.
Champs de requête simplesNonchannel_id, password, severity et les ID d’itinéraire sont des champs de requête normaux.
En-têtes HTTPNonProtégé par HTTPS/TLS, et non par E2EE.
Métadonnées de livraisonNonLe Gateway a toujours besoin de métadonnées de base pour l’authentification, le routage et la répartition.

E2EE ne remplace pas l’authentification Gateway. Vous avez toujours besoin des identifiants du Channel, des tokens Gateway Bearer facultatifs et HTTPS.

Les clients PushGo prennent en charge AES-GCM. La longueur de la clé détermine la variante AES.

Longueur de cléAlgorithmeNonce / IVBalise d’authentification
16 octetsAES-128-GCM12 octets16 octets
24 octetsAES-192-GCM12 octets16 octets
32 octetsAES-256-GCM12 octets16 octets

Disposition binaire :

[ ciphertext (N bytes) ][ auth tag (16 bytes) ][ nonce / iv (12 bytes) ]

Encodez en base64 le blob binaire complet et placez-le dans le champ API ciphertext.

Après déchiffrement, ciphertext doit contenir un objet JSON. Les clients reconnaissent les champs canoniques suivants et les réécrivent dans la charge utile de notification.

ChampTapezComportement
titlestringRemplace le titre de la notification.
bodystringRemplace le corps du message.
urlstringRemplace l’URL de destination.
imagesChaîne string[] ou JSONRemplace la liste d’images.
tagsChaîne string[] ou JSONRemplace la liste de balises.
metadataChaîne object ou JSONRemplace les métadonnées.
ChampTapezComportement
descriptionstringRemplace la description de l’événement.
statusstringRemplace le statut de l’événement.
messagestringRemplace le message d’événement.
started_atnumberRemplace l’heure de début de l’événement.
ended_atnumberRemplace l’heure de fin de l’événement.
attrsChaîne object ou JSONRemplace le correctif d’attributs d’événement.
ChampTapezComportement
primary_imagestringRemplace l’image principale.
statestringRemplace l’état de l’entité.
created_atnumberRemplace l’heure de création.
deleted_atnumberRemplace l’heure de suppression.
external_idsChaîne object ou JSONRemplace les identifiants externes.
location_typestringRemplace le type d’emplacement.
location_valuestringRemplace la valeur de l’emplacement.
locationChaîne object ou JSONRemplace l’objet de localisation.

Les champs nécessaires à la priorité d’acheminement et de livraison, tels que channel_id, password, event_id, thing_id, event_time, observed_at et severity, doivent généralement rester en texte brut.

import base64
import json
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def encrypt_payload(key_hex, payload):
key = bytes.fromhex(key_hex)
aesgcm = AESGCM(key)
nonce = os.urandom(12)
plaintext = json.dumps(payload, separators=(",", ":")).encode("utf-8")
cipher_and_tag = aesgcm.encrypt(nonce, plaintext, None)
return base64.b64encode(cipher_and_tag + nonce).decode("utf-8")
payload = {
"title": "Database lag",
"body": "Replica lag exceeded 60 seconds.",
"tags": ["encrypted", "database"],
"metadata": {"source": "replica-monitor"}
}
key_hex = "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
print(encrypt_payload(key_hex, payload))

L’exemple key_hex est une clé de 32 octets pour AES-256-GCM. Utilisez une clé aléatoire générée de manière sécurisée en production et configurez la même clé localement dans le client.

Fenêtre de terminal
curl -X POST https://gateway.pushgo.dev/message \
-H "Content-Type: application/json" \
-d '{
"channel_id": "YOUR_CHANNEL_ID",
"password": "YOUR_CHANNEL_PASSWORD",
"title": "Encrypted message",
"body": "Your client will try to decrypt ciphertext.",
"severity": "normal",
"ciphertext": "BASE64_ENCODED_CIPHERTEXT"
}'

Les title et body simples peuvent être un affichage de secours pour les clients sans clé ou lorsque le déchiffrement échoue. Mettez du contenu vraiment sensible dans le ciphertext.

ÉtatSignification
decryptOkLe déchiffrement a réussi et au moins un champ a été appliqué.
decryptFailedLe texte chiffré existe, mais le déchiffrement ou l’analyse a échoué.
notConfiguredLe client n’a configuré aucune clé utilisable.
algMismatchL’algorithme configuré ne correspond pas à la charge utile.
ProblèmeVérifier
Le déchiffrement échoueMême clé, Base64 complète et disposition binaire ciphertext + tag + nonce.
Le client ne remplace pas les champsLe JSON déchiffré doit être un objet et les noms de champs doivent être canoniques.
Gateway peut toujours voir le titreLes champs de requête simples ne sont pas protégés par E2EE ; mettez les titres sensibles dans ciphertext.
severity n’est pas cryptéCeci est recommandé car le Gateway et les services push de plateforme ont besoin d’informations prioritaires.