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-tools
Vous 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 :
ssksExportPath
est le chemin vers le fichier d’export SSKS fourni par SealdprivateKey
est une instance de SSCrypto contenant votre clé privée avec laquelle les exports ont été chiffrésoutputPath
est le chemin vers lequel écrire le fichier de sortie (le dossier doit déjà exister). Si le fichier existe déjà, il sera écrasé.appId
est votre App ID SealdssksTmrKeysPath
est 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 letwoManRuleKey
ou lerawTwoManRuleKey
pour 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.
ssksStrictPasswordsPath
est 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 lepassword
ou lerawEncryptionKey
utilisé 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 :
apiExportPath
est le chemin vers le fichier d’export de l’API Seald principale fourni par SealddecryptedIdentitiesPath
est le chemin vers le fichier obtenu à l’étape précédenteprivateKey
est une instance de SSCrypto contenant votre clé privée avec laquelle les exports ont été chiffréstmrAccessesOverEncryptionKeysPath
est 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 lesrawOverEncryptionKey
pour chaque TMR Access, sous forme de fichier JSONLines, au format suivant :
{ sessionId: string, tmrAccessId: string, rawOverEncryptionKey: string }
groupTmrTemporaryKeysOverEncryptionKeysPath
est 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 lesrawOverEncryptionKey
pour chaque Group TMR Temporary Key, sous forme de fichier JSONLines, au format suivant :
{ gTMRTKId: string, rawOverEncryptionKey: string }
symEncKeysPath
est 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.
appId
est 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
:
encryptedMessage
est le message chiffré à déchiffrerdecryptedSessionKeysPath
est le chemin vers le fichier obtenu à l’étape précédenteraw
est un booléen optionnel (par défaut àfalse
), à définir àtrue
si le message a été chiffré en mode rawsessionId
est 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
:
encryptedFileStream
est un fluxReadable
du fichier à déchiffrerdecryptedSessionKeysPath
est le chemin vers le fichier obtenu à l’étape précédentesessionId
est l’ID de session correspondant à ce fichier. Optionnel.
Cette fonction retourne :
stream
: un streamReadable
contenant 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()