Réparer maintenant
- Déposez le fichier
- La réparation s'exécute en local
- Téléchargez le résultat
Signal Desktop stocke tout votre historique de messages dans une unique base de données SQLite nommée db.sqlite, mais ce n'est pas du SQLite ordinaire : Signal utilise SQLCipher, une bifurcation qui chiffre de façon transparente l'intégralité du fichier en AES-256, en-tête compris. Autrement dit, un moteur de sauvetage de pages (celui-ci y compris) ne voit qu'un bruit à haute entropie et répond file is not a database (« le fichier n'est pas une base de données ») tant que le fichier n'est pas déchiffré. Récupérer une base de données Signal cassée se fait donc en deux étapes : d'abord la déchiffrer localement avec la clé qui se trouve déjà sur votre machine, ce qui produit un fichier SQLite en clair ; ensuite, déposez ce fichier en clair ci-dessus et l'outil parcourt ses pages dans votre navigateur et reconstruit une base de données propre à partir de chaque ligne qu'il parvient encore à décoder. La clé comme les données restent sur votre appareil.
Le db.sqlite de Signal est chiffré — déchiffrez-le avant tout sauvetage
La base de données de Signal Desktop se trouve dans ~/Library/Application Support/Signal/sql/db.sqlite sous macOS, dans %AppData%\Signal\sql\db.sqlite sous Windows et dans ~/.config/Signal/sql/db.sqlite sous Linux. Comme SQLCipher chiffre le fichier entier, exécuter file db.sqlite affiche des octets aléatoires au lieu de la signature habituelle SQLite format 3\0. Tout outil SQLite ordinaire — l'interpréteur sqlite3, DB Browser ou le moteur de sauvetage de cette page — voit du texte chiffré, pas des pages, et ne peut ni ne va deviner la clé.
La clé SQLCipher de 64 caractères hexadécimaux se trouve dans config.json, à côté de la base de données. Dans les anciennes versions, elle est stockée en clair sous un champ key ; depuis 2024, Signal l'enveloppe sous encryptedKey via l'API safeStorage d'Electron — adossée à l'élément du trousseau macOS nommé « Signal Safe Storage », à DPAPI sous Windows et à gnome-libsecret / kwallet sous Linux. Comme l'enveloppe est liée à votre compte du système d'exploitation, vous ne pouvez déballer la clé que sur la même machine et le même utilisateur qui l'ont créée.
Une fois la clé brute en main, ouvrez la base de données dans n'importe quel outil compatible SQLCipher (le CLI sqlcipher, ou une version de DB Browser for SQLite compilée avec SQLCipher) et exécutez PRAGMA key = "x'<clé-64-hex>'"; suivi de PRAGMA cipher_compatibility = 4; — Signal embarque SQLCipher 4. Exportez ensuite une copie en clair avec .recover ou avec VACUUM INTO 'plain.sqlite'. C'est ce fichier en clair que vous déposez ici. Travaillez toujours sur une copie octet par octet, jamais sur votre unique original.
Ce que « malformed » signifie dans une base de données Signal
Une fois déchiffrée, une base de données Signal est un fichier SQLite ordinaire : un tableau plat de pages de taille fixe (4096 octets chacune). La page 1 contient l'en-tête et le schéma ; chaque table et chaque index est un arbre B de pages internes qui pointent vers le bas, vers des pages feuilles qui contiennent les lignes. Les données de Signal résident dans des tables comme messages (chaque ligne identifiée par id, avec conversationId, sent_at, received_at, type, une colonne body et une colonne json qui porte l'enregistrement complet du message), conversations, reactions, sessions, items, ainsi qu'un index de recherche plein texte messages_fts (FTS5).
La corruption est presque toujours localisée. Une coupure de courant en pleine écriture, une synchronisation interrompue, une page déchirée sur un support qui a menti sur son vidage (flush) — un seul pointeur d'un arbre B cesse de concorder avec les données, et SQLite lève SQLITE_CORRUPT : Error: database disk image is malformed (11). Il refuse le fichier entier dès l'instant où il ne peut plus se fier à la structure, alors même que vos autres tables reposent intactes dans leurs pages feuilles. Le fichier semble bien plus atteint qu'il ne l'est.
L'erreur voisine file is not a database (« le fichier n'est pas une base de données », SQLITE_NOTADB, code 26) a ici deux significations : soit la signature de 16 octets de l'en-tête a été endommagée (les pages situées derrière sont souvent intactes), soit — bien plus fréquent avec Signal — vous avez pointé un outil ordinaire vers le fichier encore chiffré. Si vous la voyez avant le déchiffrement, c'est le chiffrement qui parle, pas un dommage.
Ce que le sauvetage de pages récupère d'une BD Signal — et ce qu'il ne peut pas
Le sauvetage de pages ne répare pas le fichier cassé sur place ; il fait ce que fait le .recover de SQLite lui-même. Il parcourt le fichier déchiffré page par page et, pour chaque page qui ressemble à une feuille de table, lit chaque cellule directement — rowid, types sériels, valeurs — et réinsère chaque ligne décodable dans une base de données neuve et vide. Les pages endommagées sont ignorées ; les pages lisibles livrent leurs lignes que l'arbre B qui les indexait ait survécu ou non. Les lignes que la chaîne de pointeurs n'atteint plus sont retrouvées par un balayage brut, et les lignes dont la table d'origine ne peut être identifiée vont dans une table lost_and_found indexée par page et par cellule plutôt que d'être jetées. En pratique, vos lignes de messages reviennent avec leur body et leur json intacts, même lorsque c'est l'index FTS ou l'arbre d'une seule conversation qui a cassé.
Si le plantage a laissé un fichier voisin -wal (le mode WAL prépare les transactions validées les plus récentes avant de les reporter — checkpoint — dans db.sqlite), c'est là que se trouvent vos messages les plus récents, mais il est lui aussi chiffré avec SQLCipher : déchiffrez-le donc en même temps que le fichier principal. À partir d'une base de données en clair et de son WAL en clair, le moteur superpose les trames validées avant l'analyse pour que la récupération reflète la dernière transaction validée.
Les limites, en toute honnêteté, sont réelles. Les pièces jointes ne sont pas dans la base de données : Signal stocke les photos, les vidéos et les fichiers sous forme de blobs séparés et chiffrés individuellement dans attachments.noindex/, si bien qu'une ligne de messages récupérée conserve le pointeur et les métadonnées, mais récupérer la BD ne déchiffre pas le média lui-même. Tout ce qui a été physiquement écrasé ou tronqué à la fin du fichier est perdu : un fichier SQLite n'a aucune redondance permettant de le reconstruire. Et le résultat récupéré est toujours suspect : comme l'analyse lit des cellules brutes, y compris les pages de la freelist, des messages supprimés peuvent réapparaître et une valeur peut revenir avec la mauvaise classe de stockage ; vérifiez donc le résultat par rapport à une source fiable et connue avant de vous y fier.
Pourquoi cela doit rester sur votre propre machine
La base de données d'une messagerie est le fichier que vous voudriez le moins voir sur un serveur que vous ne contrôlez pas : c'est chaque conversation, chaque contact et chaque groupe que vous avez conservés. Les services de « réparation » fondés sur le téléversement copient ce fichier sur une infrastructure que vous ne pouvez pas inspecter, sous des conditions de conservation que vous n'avez pas rédigées — et, pour une base de données Signal, cela réduit à néant, en silence, tout l'intérêt d'utiliser Signal.
Ici, le sauvetage s'exécute entièrement dans l'onglet de votre navigateur : le fichier en clair est lu depuis le disque, reconstruit localement et téléchargé, et vous pouvez ouvrir l'onglet Réseau (Network) et constater que 0 octet sort. Tout aussi important : l'étape de déchiffrement reste elle aussi locale — votre clé SQLCipher provient de votre propre trousseau (Keychain) (ou de config.json) et n'est utilisée que par un outil de votre machine, jamais transmise. Récupérer une base de données Signal de cette manière, c'est ne confier ni les données ni la clé à aucun tiers.
Ce que cela peut et ne peut pas réparer
Peut réparer
- Une base de données Signal que vous avez déchiffrée en clair (avec sqlcipher ou une version de DB Browser compilée avec SQLCipher) et qui indique ensuite « database disk image is malformed »
- Les lignes de messages — la colonne body et l'enregistrement json complet — extraites des pages feuilles de l'arbre B ayant survécu
- Les tables conversations, reactions et autres lorsqu'une seule page ou un seul pointeur défectueux a fait tomber tout le fichier
- Les lignes que la chaîne de pointeurs n'atteint pas, via une analyse brute des pages, les lignes non attribuables étant placées dans une table lost_and_found
- Les messages les plus récents issus d'un fichier compagnon -wal déchiffré, superposés avant l'analyse
Ne peut pas réparer
- Le db.sqlite encore chiffré lui-même : déchiffrez-le d'abord en local ; le moteur récupère du SQLite en clair, pas du texte chiffré SQLCipher
- Tout ce qui n'a pas la clé : un encryptedKey que vous ne pouvez pas déballer (trousseau perdu, autre machine ou autre utilisateur) ne deviendra jamais du SQLite lisible
- Les pièces jointes des messages : elles existent sous forme de fichiers chiffrés séparément dans attachments.noindex/, pas à l'intérieur de la base de données
- Les messages physiquement écrasés ou tronqués à la fin du fichier : aucun outil ne peut les inventer
- Une garantie d'exactitude : des lignes supprimées peuvent réapparaître et les types peuvent changer ; vérifiez les données récupérées avant de vous y fier
Si une réparation échoue, nous vous expliquons pourquoi (données manquantes ou structure endommagée), et vous n'êtes jamais facturé pour une réparation échouée.