Comment un gros envoi chiffré survit à une connexion coupée
Un envoi hébergé de dizaines ou de centaines de gigaoctets dure assez longtemps pour que quelque chose tourne mal : le Wi-Fi change de borne, un ordinateur portable se met en veille, un onglet est rechargé. Transferify traite cela à deux niveaux. Tant que la page est ouverte, une connexion coupée ne fait que mettre l’envoi en pause. Si la page a disparu, le même navigateur peut reprendre l’envoi plus tard et n’envoyer que ce qui manque.
La seconde partie est plus difficile qu’il n’y paraît, car chaque fichier est chiffré dans votre navigateur avant d’être envoyé. Cet article explique comment les deux niveaux fonctionnent, et pourquoi reprendre un envoi chiffré demande une attention particulière.
Tant que la page est ouverte : attendre, réessayer, continuer
Un fichier hébergé part en de nombreuses parties distinctes, et chaque partie est sa propre requête (comment l’envoi lui-même fonctionne). Quand une requête échoue parce que la connexion s’est coupée ou a expiré, elle est réessayée :
- La première nouvelle tentative attend une demi-seconde au plus, et la limite de chaque pause suivante double, jusqu’à 30 secondes.
- Chaque pause est tirée au hasard dans la moitié supérieure de sa limite, pour que de nombreuses parties qui ont échoué ensemble ne réessaient pas toutes au même instant.
- Une requête continue d’essayer pendant dix minutes d’échecs au plus, avant que l’envoi s’arrête.
- Tant que votre navigateur indique qu’il est hors ligne, l’envoi attend le retour du réseau au lieu de consommer ces dix minutes, quelle que soit la durée de la panne.
- Une partie qui n’envoie rien pendant deux minutes est considérée comme une connexion perdue et réessayée.
- Chaque nouvelle tentative d’une partie utilise une adresse d’envoi nouvellement signée : une adresse qui a expiré pendant que vous étiez hors ligne est donc remplacée.
Une partie défaillante n’arrête pas les autres. Seule une partie qui a épuisé ses tentatives met fin à l’envoi, et même alors l’envoi s’arrête à un point où vous pouvez le reprendre.
Une réponse est traitée différemment. Si notre service répond qu’il n’a pas réussi à démarrer l’envoi d’un fichier vers le stockage, cette requête est retentée trois fois en une ou deux secondes, puis l’envoi s’arrête de la même manière au lieu de réessayer pendant des minutes, car cette réponse ne signifie pas que votre connexion s’est coupée.
Tout cela s’applique quand vous envoyez un nouveau transfert hébergé. L’ajout de fichiers à un transfert déjà envoyé, et l’envoi de fichiers vers la demande de fichiers de quelqu’un, gardent trois tentatives rapides à la place : une connexion perdue s’y voit donc tout de suite.
Après un rechargement : reprendre dans le même navigateur
Avant que le premier octet d’un envoi quitte votre appareil, votre navigateur note ce dont il aurait besoin pour le reprendre plus tard. Cet enregistrement est conservé dans l’espace de stockage propre à votre navigateur pour ce site (IndexedDB), sur votre appareil, et contient :
- la clé de chiffrement du transfert, stockée comme objet de clé du navigateur,
- une valeur aléatoire secrète dont dérivent les nonces des fichiers (expliquée plus bas),
- les fichiers qui font partie de l’envoi, avec leurs noms, leurs tailles et leurs dates de modification,
- pour un transfert en mode Zéro connaissance, le lien de partage terminé avec sa clé.
L’enregistrement reste sur votre appareil. La valeur secrète qu’il contient ne nous est jamais envoyée, pas plus que la clé brute : en mode par défaut, notre service ne conserve qu’une copie de la clé enveloppée par une clé d’AWS KMS, et en mode Zéro connaissance aucune copie. L’enregistrement est supprimé quand l’envoi se termine, quand vous l’abandonnez, ou quand il ne peut plus être repris. Un visiteur qui ne démarre jamais d’envoi hébergé ne se voit rien écrire du tout.
Quand vous revenez, connecté au compte qui a démarré l’envoi, Transferify propose de reprendre. Il demande au stockage quelles parties de chaque fichier il détient déjà, garde toute partie dont la longueur est exactement celle attendue, et envoie le reste. Les fichiers terminés avant l’interruption sont entièrement ignorés.
Retrouver vos fichiers
Pour les envois jusqu’à 2 Gio au total, et seulement quand votre navigateur dispose d’au moins deux fois la taille de l’envoi en espace libre, le navigateur conserve aussi une copie des fichiers eux-mêmes : vous n’avez donc pas à les choisir de nouveau. Pour tout ce qui est plus volumineux, vous choisissez de nouveau les mêmes fichiers.
Transferify reconnaît chaque fichier à son nom, à sa taille et à sa date de dernière modification. Un fichier que vous avez modifié entre-temps a une nouvelle date et est refusé, car les parties déjà dans le stockage contiennent l’ancien contenu et le reste doit être constitué des mêmes octets.
Pourquoi reprendre un envoi chiffré demande de l’attention
AES-GCM, le chiffrement qu’utilise Transferify, a une règle qui ne doit jamais être enfreinte : la même clé et le même nonce ne doivent jamais sceller deux données différentes. Quiconque verrait les deux résultats pourrait apprendre en quoi les deux données diffèrent, et pourrait forger des données sous cette clé.
Un envoi repris doit s’approcher de cette règle, volontairement. Pour raccorder les parties que le stockage détient déjà, les parties manquantes doivent être chiffrées de nouveau en exactement les octets qu’elles auraient eus. Cela suppose la même clé et les mêmes nonces qu’avant. Deux garde-fous rendent cela sûr.
Des nonces que vous seul pouvez reconstruire. Pour un envoi hébergé, la valeur de départ des nonces de chaque fichier n’est pas un nombre aléatoire perdu quand la page se ferme. Elle est dérivée avec HMAC-SHA-256 à partir de la valeur aléatoire secrète de l’enregistrement de votre navigateur, de la position du fichier dans votre sélection, de l’identifiant du fichier et de l’envoi vers le stockage auquel il appartient. Votre navigateur peut la dériver de nouveau après un rechargement. Nos serveurs ne le peuvent pas, car le secret ne quitte jamais votre appareil.
La preuve que les octets n’ont pas changé. Avant qu’une partie quitte votre appareil, le navigateur conserve le tag d’authentification de chaque bloc qu’elle contient. Quand un envoi reprend, le navigateur chiffre de nouveau chaque bloc et compare le nouveau tag au tag conservé avant d’envoyer quoi que ce soit. Des tags identiques signifient les mêmes données. Un tag différent signifie que le fichier a changé, même si son nom, sa taille et sa date sont restés identiques. Ce fichier repart alors du début, dans un nouvel envoi vers le stockage, avec de nouveaux nonces : aucun nonce n’est ainsi jamais utilisé deux fois pour des données différentes.
Les limites
- Un envoi ne peut être repris que dans le navigateur et sur l’appareil qui l’ont démarré, car le secret dont dérivent ses nonces n’est conservé que dans ce navigateur.
- La proposition de reprise dure jusqu’à sept jours après le début de l’envoi, ou jusqu’à l’expiration prévue de son lien si elle survient plus tôt. Le stockage garde les parties d’un envoi inachevé pendant sept jours à partir du début de l’envoi de chaque fichier : elles sont donc encore là aussi longtemps que la proposition tient.
- Une seule page à la fois peut travailler sur un envoi donné. Si un autre onglet le reprend déjà, la page vous le dit au lieu de démarrer une seconde copie.
- Si le transfert a été supprimé ou a expiré entre-temps, il n’y a plus rien à reprendre, et la page vous l’indique.
- Si votre navigateur n’autorise pas ce site à conserver des données, l’envoi s’exécute quand même, mais il ne pourra pas être repris après un rechargement.
Essayez
Démarrez un gros envoi hébergé, fermez l’onglet en cours de route, puis rouvrez Transferify dans le même navigateur : l’envoi vous est proposé de nouveau. Envoyez un fichier maintenant.
Questions fréquentes
Que se passe-t-il si ma connexion se coupe pendant un envoi ?
L’envoi attend et réessaie. Une requête est retentée pendant dix minutes d’échecs au plus, avec des pauses de plus en plus longues entre les tentatives, et le temps que votre navigateur passe hors ligne ne compte pas dans ces dix minutes. Les parties déjà arrivées dans le stockage ne sont pas renvoyées.
Puis-je reprendre un envoi après avoir fermé l’onglet ou rechargé la page ?
Oui, dans le même navigateur, sur le même appareil, connecté au même compte, jusqu’à sept jours après le début de l’envoi, ou jusqu’à l’expiration prévue de son lien si elle survient plus tôt. Quand vous rouvrez Transferify, il propose de reprendre et n’envoie que ce que le stockage ne détient pas déjà.
Puis-je reprendre l’envoi sur un autre ordinateur ?
Non. Le secret dont dérivent les nonces d’un envoi inachevé n’est conservé que dans le navigateur qui l’a démarré et ne le quitte jamais. Un envoi repris reste donc dans ce navigateur.
Dois-je choisir de nouveau les fichiers ?
Pour les envois jusqu’à 2 Gio au total, votre navigateur garde généralement sa propre copie : ce n’est donc pas nécessaire. Pour les envois plus volumineux, vous choisissez de nouveau les mêmes fichiers, et Transferify vérifie qu’il s’agit bien des mêmes fichiers avant de reprendre.