Réversibilité
Pour prévoir les cas ou vous auriez besoin d'arrêter d'utiliser le SDK Seald, et de récupérer les données de votre application dans un état déchiffré, nous avons prévu un outil de réversibilité.
Cet outil utilise un export des données Seald pour votre application, venant de nos serveurs API et SSKS, ainsi qu'un export de certaines données venant de votre "backend", pour pouvoir déchiffrer les données chiffrées avec le SDK Seald.
Attention, l'usage de cet outil casse le chiffrement de bout-en-bout. Il est prévu pour les cas exceptionnels où vous avez besoin d'arrêter d'utiliser le SDK Seald, et aucunement pour un usage courant.
Si vous êtes intéressés par cet outil, nous vous recommandons fortement de tester la procédure de réversibilité par avance sur votre environnement de Staging.
WARNING
Cette procédure de réversibilité nécessite que vous ayez accès aux identités de chaque utilisateur. Ce n'est pas toujours possible, par exemple si vous utilisez seulement la protection par mot de passe, avec un mot de passe qui n'est connu qu'aux utilisateurs.
Si vous utilisez le mécanisme de 2-man-rule pour stocker les identités des utilisateurs, vous devriez pouvoir suivre cette procédure et déchiffrer les identités des utilisateurs avec les exports SSKS de Seald plus l'export de votre serveur.
Si vous n'utilisez pas le 2-man-rule, vous devrez peut-être deployer du code coté client pour récupérer les identités de vos utilisateurs.
Export des données Seald
Pour obtenir cet export, vous devez contacter le support Seald, qui vous fournira ces fichiers.
Nous pouvons également mettre en place un export régulier de ces données vers un Object Storage compatible S3 sous votre contrôle, si vous le souhaitez. Dans ce cas, nous exporterons périodiquement ces données vers vos serveurs.
Ces données sont chiffrées pour une clé privée. Cette clé privée peut être sous votre contrôle ; dans ce cas nous recommandons de la stocker hors-ligne, sur un ou plusieurs supports physiques (clé USB, disque dur, etc.), stockés dans un lieu sur. La clé privée peut également être mise sous séquestre chez un tiers de confiance, tel que l'Agence de Protection des Programmes (APP), qui pourra vous la fournir en cas de cloture de votre contrat, ou de défaillance contractuelle de Seald (des frais supplémentaires pour cette séquestre peuvent s'appliquer).
Export des données de votre backend
Vous devez également exporter certaines données de votre backend, pour pouvoir déchiffrer les données chiffrées avec le SDK Seald. Ces données sont optionnelles, selon les fonctionnalités du SDK Seald que vous utilisez dans votre application.
Ces données, et le format de l'export attendu, sont décrites dans la section Utilisation de l'outil de réversibilité ci-dessous.
Vous devez bien entendu également vous assurer d'avoir accès aux données chiffrées à déchiffrer.
Installation de l'outil de réversibilité
L'outil de réversibilité est une librairie JavaScript, disponible en tant que paquet npm : https://www.npmjs.com/package/@seald-io/reversibility-tools.
Vous pouvez l'installer dans votre projet en utilisant la commande suivante :
npm install @seald-io/reversibility-toolsVous pouvez ensuite l'utiliser dans votre code JavaScript.
Utilisation de l'outil de réversibilité
L'outil de réversibilité est une librairie Node.JS, destinée à être utilisée dans des scripts JavaScript que le développeur écrit pour réaliser ce processus.
Ce processus est fait en 3 étapes :
- Obtention d'une base de données d'identités déchiffrées
- Obtention d'une base de données de clés de session déchiffrées
- Déchiffrement des données elles-mêmes
Obtention d'une base de données d'identités déchiffrées
Une base de données d'identités déchiffrées (le résultat de cette étape) est un fichier JSONLines, contenant :
{ sealdId: string, deviceId: string, identity: string }Le champ identity contient l'encodage Base64 du buffer d'identité.
Ce fichier peut être construit de plusieurs manières.
Premièrement, cela peut être fait directement par le développeur, en appelant sealdSdk.exportIdentity() sur ses clients, puis en renvoyant ces identités à son serveur, et en construisant ce fichier manuellement.
Sinon, cette base de données peut être obtenue via la fonction decryptSsksExport(ssksExportPath, privateKey, outputPath, { appId, ssksTmrKeysPath, ssksStrictPasswordsPath }) des outils de réversibilité.
Dans cet appel de fonction :
ssksExportPathest le chemin vers le fichier d’export SSKS fourni par SealdprivateKeyest une instance de SSCrypto contenant votre clé privée avec laquelle les exports ont été chiffrésoutputPathest le chemin vers lequel écrire le fichier de sortie (le dossier doit déjà exister). Si le fichier existe déjà, il sera écrasé.appIdest votre App ID SealdssksTmrKeysPathest un argument optionnel, si vous souhaitez récupérer les identités depuis SSKS 2MR. C’est le chemin vers un fichier exporté depuis votre base de données, contenant letwoManRuleKeyou lerawTwoManRuleKeypour chaque utilisateur de votre app, sous forme de fichier JSONLines, au format suivant :
{ userId: string, sealdId?: string, deviceId?: string, rawTwoManRuleKey?: string, twoManRuleKey?: string }Chaque ligne doit contenir une seule, et une seule, des clés rawTwoManRuleKey ou twoManRuleKey. Les champs sealdId et deviceId sont optionnels, et servent à vérifier que l’identité déchiffrée correspond bien à ce qui est attendu.
ssksStrictPasswordsPathest un argument optionnel, si vous souhaitez récupérer les identités depuis SSKS Password. C’est le chemin vers un fichier exporté depuis votre base de données, contenant lepasswordou lerawEncryptionKeyutilisé pour stocker son identité sur SSKS Password pour chaque utilisateur de votre app, sous forme de fichier JSONLines, au format suivant :
{ userId: string, sealdId?: string, deviceId?: string, password?: string, rawEncryptionKey?: string }Chaque ligne doit contenir une seule, et une seule, des clés password ou rawEncryptionKey. Les champs sealdId et deviceId sont optionnels, et servent à vérifier que l’identité déchiffrée correspond bien à ce qui est attendu.
Obtention d'une base de données de clés de session déchiffrées
Une fois que vous avez la base de données d’identités déchiffrées, vous pouvez utiliser la fonction decryptApiExport(apiExportPath, decryptedIdentitiesPath, privateKey, outputPath, { tmrAccessesOverEncryptionKeysPath?, symEncKeysPath?, appId? }) des outils de réversibilité.
Dans cet appel de fonction :
apiExportPathest le chemin vers le fichier d’export de l’API Seald principale fourni par SealddecryptedIdentitiesPathest le chemin vers le fichier obtenu à l’étape précédenteprivateKeyest une instance de SSCrypto contenant votre clé privée avec laquelle les exports ont été chiffréstmrAccessesOverEncryptionKeysPathest un argument optionnel, si vous souhaitez récupérer les clés de session à partir des TMR Accesses. Il s’agit du chemin vers un fichier exporté depuis votre base de données, contenant lesrawOverEncryptionKeypour chaque TMR Access, sous forme de fichier JSONLines, au format suivant :
{ sessionId: string, tmrAccessId: string, rawOverEncryptionKey: string }groupTmrTemporaryKeysOverEncryptionKeysPathest un argument optionnel, si vous souhaitez récupérer les clés de session depuis les "Group TMR Temporary Keys". Il s’agit du chemin vers un fichier exporté depuis votre base de données, contenant lesrawOverEncryptionKeypour chaque Group TMR Temporary Key, sous forme de fichier JSONLines, au format suivant :
{ gTMRTKId: string, rawOverEncryptionKey: string }symEncKeysPathest un argument optionnel, si vous souhaitez récupérer les clés de session depuis SymEncKeys. Il s’agit du chemin vers un fichier exporté depuis votre base de données, contenant les Sym Enc Keys, sous forme de fichier JSONLines, au format suivant :
{ sessionId: string, symEncKeyId: string, rawSecret?: string, rawSymKey?: string, password?: string }Chaque ligne doit contenir soit password, soit le couple rawSecret et rawSymKey, mais pas les deux.
appIdest l’ID de votre application Seald. Il est requis uniquement si vous fournissezsymEncKeysPath.
Cela produira un fichier JSONLines au format suivant :
{ sessionId: string, key: string }Déchiffrement des données elles-mêmes
Une fois que vous avez la base de données des clés de session déchiffrées, vous pouvez utiliser les fonctions decryptMessage(encryptedMessage, decryptedSessionKeysPath, { raw , sessionId }) et decryptFile(encryptedFileStream, decryptedSessionKeysPath, { sessionId }) pour déchiffrer respectivement les messages et les fichiers.
Dans l’appel de la fonction decryptMessage :
encryptedMessageest le message chiffré à déchiffrerdecryptedSessionKeysPathest le chemin vers le fichier obtenu à l’étape précédenterawest un booléen optionnel (par défaut àfalse), à définir àtruesi le message a été chiffré en mode rawsessionIdest l’ID de session correspondant à ce message. Optionnel si le message n’est pas en mode raw. Obligatoire si le message est en mode raw.
Cette fonction retourne le contenu du message déchiffré sous forme de string.
Dans l’appel de la fonction decryptFile :
encryptedFileStreamest un fluxReadabledu fichier à déchiffrerdecryptedSessionKeysPathest le chemin vers le fichier obtenu à l’étape précédentesessionIdest l’ID de session correspondant à ce fichier. Optionnel.
Cette fonction retourne :
stream: un streamReadablecontenant le contenu du fichier déchiffrépromise: une Promise qui se résout une fois le parsing terminé, et qui contient la taille du fichiersize, le nom du fichierfilename, la version du protocoleprotocol, et l’ID de session analysémid
Exemple d'utilisation
Un exemple complet d'utilisation de l'outil de réversibilité est disponible sur GitHub, à l'adresse https://github.com/seald/seald-reversibility-tools-demo.
Voici également un exemple basique d'utilisation de l'outil de réversibilité :
const { node: sscrypto } = require('sscrypto')
const fs = require('node:fs')
const {
decryptApiExport,
decryptFile,
decryptMessage,
decryptSsksExport
} = require('@seald-io/reversibility-tools')
// Votre Seald Application Id
const appId = 'YOUR_APP_ID'
const databaseReversibilityDemo = async () => {
// Crée un dossier de sortie pour les fichiers déchiffrés
await fs.promises.mkdir('./clear-files', { recursive: true })
// Charge et instancie une SSCrypto.PrivateKey
// Ceci est la clé privée utilisée pour chiffrer les exports Seald
const privateKeyB64 = await fs.promises.readFile('./seald-database-exports/private_key', 'utf8')
const privateKeyInstance = sscrypto.PrivateKey.fromB64(privateKeyB64)
// Premièrement, déchiffrer l'export des identités
// Cela créera un fichier contenant les SealdIds et leurs clés privées associées
await decryptSsksExport(
'./seald-database-exports/test-ssks.backup',
privateKeyInstance,
'./clear-files/identities.jsonl',
{
appId,
ssksTmrKeysPath: './exports/ssks-tmr-keys.jsonl',
ssksStrictPasswordsPath: './exports/ssks-strict-passwords.jsonl'
}
)
// Deuxièmement, déchiffrer l'export de l'API
// Cela créera un fichier associant les IDs de session et la clé de chiffrement symétrique correspondante.
await decryptApiExport(
'./seald-database-exports/api.backup',
'./clear-files/identities.jsonl',
privateKeyInstance,
'./clear-files/sessions.jsonl',
{
tmrAccessesOverEncryptionKeysPath: './exports/tmr-accesses-over-encryption-keys.jsonl',
tmrTemporaryKeysOverEncryptionKeysPath: './exports/group-tmr-temp-key-over-encryption-key.jsonl',
symEncKeysPath: './exports/sym-enc-keys.jsonl',
appId
}
)
// Maintenant que la base de données Seald a été entièrement déchiffrée, nous pouvons déchiffrer n'importe quel message
// Déchiffre un fichier
const res = decryptFile(
fs.createReadStream('./encrypted-files/test.txt.seald'),
'./clear-files/sessions.jsonl'
)
await fs.promises.writeFile('./clear-files/test.txt', res.stream)
// Déchiffre un message
const encrypted = await fs.promises.readFile('./encrypted-files/test-message.bin', 'utf8')
const decryptedMessage = await decryptMessage(encrypted, './clear-files/sessions.jsonl')
await fs.promises.writeFile('./clear-files/test-message.txt', decryptedMessage)
}
databaseReversibilityDemo()