Ted écrit des trucs

C'est pas toujours très intéressant, mais il fait ce qu'il peut.

Stocker des Bitcoin de façon sûre

posté le
modifié pour la dernière fois le

J'ai eu la chance d'entendre parler de Bitcoin assez tôt, et de m'y intéresser assez pour être rapidement enthousiasmé par les possibilités et (à mon humble avis) le potentiel disruptif de cette technologie. En conséquence, j'ai acheté quelques Bitcoin à l'époque où ils ne valaient pas encore grand-chose, et au fil des mois, je me suis rendu compte que vu leur valeur, il faudrait peut-être que je les stocke (au moins en partie) de façon un peu sécurisée. Je me suis renseigné et ce billet décrit la solution que j'ai choisie, qui est assez peu commune pour que ça vaille la peine que je la détaille en français, et assez élégante pour que je puisse l'exposer publiquement sans avoir peur que l'on se serve de ces informations contre moi.

Note : si vous ne connaissez pas bien le fonctionnement des Bitcoin, la seule chose qu'il est nécessaire de savoir pour comprendre cet article est la chose suivante. Les Bitcoin (qui ont de la valeur monétaire, donc que l'on veut protéger contre les incendies et les pirates, et transmettre à nos proches en cas d'accident) sont stockés sur des adresses, et pour pouvoir les utiliser, il faut en avoir la clé privée. Stocker des Bitcoin se résume donc à stocker une clé privée, qui est essentiellement une chaîne de caractères — ou, parce que c'est plus pratique, un QR code :

QR code

(pas la peine de vous embêter, il n'y a rien dessus).

Le problème

Je voulais que mon système réponde à trois critères essentiels :

  • être résistant aux attaques extérieures — par « attaques », j'entends aussi bien un piratage d'un ou plusieurs de mes appareils qu'un possible vol de mes affaires ;
  • être sûr, c'est-à-dire que je veux minimiser les risques que je perde l'accès à mes Bitcoin — par exemple, en cas d'oubli de mot de passe, de mort d'un disque dur ou d'un autre type d'accident compromettant l'intégrité de mes données ;
  • et être résilient, c'est-à-dire que si je meurs, je veux être sûr que quelqu'un de confiance puisse y avoir accès.

Malgré ce que peuvent dire d'un ton emphatique les évangélistes du monde du Bitcoin, c'est très loin d'être évident de trouver une solution qui satisfasse tous ces critères d'un coup. La solution classique se base sur un mot de passe complexe et un chiffrement de portefeuille (en général avec BIP-38), mais je trouve que ça a un inconvénient assez majeur : si le mot de passe est assez complexe pour qu'il ne soit pas devinable par un attaquant, il faut soit le noter quelque part, soit devoir le retenir.

Dans le premier cas, on prend le risque de se faire voler le papier en question, ou bien qu'il soit détruit dans un accident — et si on l'écrit sur plusieurs papiers, on diminue le second risque en augmentant le premier. Ou alors, on fait appel à quelqu'un dont c'est le métier de garder des documents précieux (dans un testament chez le notaire ou dans le coffre d'une banque), mais ça tue un peu le principe d'une monnaie décentralisée que l'on peut utiliser sans intermédiaire.

Dans le second cas, il faut avoir une confiance absolue en ses propres capacités de mémorisation, ce qui me semble un peu trop optimiste (un accident qui fait subir un choc au mauvais endroit du cerveau est vite arrivé), et ça ne satisfait pas mon troisième critère.

La solution naturelle est de séparer l'information « clé privée chiffrée » avec « mot de passe de la clé ». Mettre le QR code de la clé chiffrée à plusieurs endroits sûrs, et retenir le mot de passe, en faisant aussi une sauvegarde du mot de passe dans (au moins) un endroit sûr, différent de l'endroit où a mis la clé chiffrée (évidemment). En se débrouillant pour qu'en cas d'accident, nos proches puissent avoir accès à ces deux informations.

Une politique classique en termes de sauvegardes considère que pour être sûr de ne pas perdre une donnée, il faut en avoir trois copies à trois endroits différents, sur au moins deux supports distincts. Dans notre situation où l'on a deux informations qui ne doivent pas se « toucher », il faut donc six lieux de stockage entièrement séparés si on veut avoir une sécurité correcte. Aucun, bien sûr, ne doit être connecté à Internet : on veut avoir la certitude que si une donnée est compromise, on s'en rendra compte et on pourra prendre les mesures qui s'imposent. Du coup, ça fonctionne et c'est théoriquement solide, mais c'est pas très pratique à mettre en place.

La solution

Si on veut avoir une solution plus simple à mettre en place, il ne faut donc pas séparer l'information « clé privée chiffrée » et « mot de passe » : autrement dit, ne pas utiliser de mot de passe. Mais si l'on fait ça et que l'on met la clé privée dans un unique endroit, ça n'est ni résistant aux attaques ni sûr. Donc, on va séparer la clé privée en plusieurs morceaux, de telle sorte à ce que chaque morceau pris à part ne soit pas suffisant pour reconstituer l'information complète.

Un peu comme un puzzle… Sauf que pas vraiment. Un puzzle a une caractéristique pénible : si l'on perd une pièce, on ne peut pas reconstituer le puzzle entier. Et en plus, la connaissance d'une pièce donne une information non négligeable sur le puzzle final : plus on dispose de pièces, plus c'est facile de « deviner » (comprendre : bruteforcer) celle(s) qui manque(nt). Mais ça tombe bien, le monde merveilleux de la cryptographie a une solution toute prête à ce problème, et ça s'appelle SSSS, comme Shamir's Secret Sharing Scheme.

Avec ce système, on peut choisir deux entiers t et n (où t≤n), une clé secrète, et obtenir n morceaux de la clé qui vérifient deux propriétés sympa :

  • si on dispose de t morceaux différents (n'importe lesquels), on peut reconstituer la clé secrète ;
  • et si on dispose de strictement moins de t morceaux, alors on a aucune information supplémentaire sur la clé (le problème « trouver la clé » est aussi difficile que si on n'a aucun morceau).

Une fois qu'on a nos morceaux, on les met à des endroits différents, et si 1<t<n, on obtient toutes les propriétés voulues : en cas de perte ou de vol d'un des morceaux, rien n'est compromis (puisqu'il faut au moins 2 morceaux pour avoir accès aux données) et on a peut retrouver l'information de départ (puisque l'on dispose toujours de n-1 morceaux, et t≤(n-1)).

En fait, si 2<t<(n-1), on peut même se faire voler ou perdre deux morceaux sans que ça soit problématique. Et en fonction du niveau de sécurité que l'on désire, on peut adapter le nombre de morceaux. t=2 et n=3 est la solution « minimale », qui permet d'avoir une sécurité raisonnable (le cas de figure « on se fait voler ou on perd 2 morceaux à la fois » est extrêmement peu probable si ils sont dans des endroits différents) et beaucoup plus plus simple à mettre en place et à maintenir que la solution précédente. Si l'on veut plus de sécurité face aux attaques venant de gens malicieux, il faut augmenter t et n en même temps ; et si l'on veut plus de résilience face à l'éventualité d'une perte de données, il faut augmenter n tout seul.

Mise en pratique

La première chose à faire est de choisir t et n, ce qui dépend du nombre d'endroits de stockage dont on dispose. Pour t=2 et n=3, il suffira de confier deux morceaux à deux personnes de confiance, et en garder un avec soi. Ou bien, une seule personne de confiance, et deux endroits sûrs que l'on a à notre disposition. Dans la suite, on va supposer que t=2 et n=3, c'est facile d'adapter à la solution choisie.

Ensuite, il faut créer notre clé privée. On va faire ça sur un ordinateur déconnecté d'Internet, depuis un Live-CD et qui dispose d'une imprimante. Tout ce qui suit la génération de la clé privée doit être fait depuis une machine complètement déconnectée du réseau, pour éviter qu'un virus ne puisse envoyer à un attaquant les informations générées. De la même façon, si le modèle de l'imprimante est récent et qu'elle est connectée à Internet, il faut débrancher sa connexion (voire la réinitialiser avant et après aux paramètres d'usine, si on a pas confiance).

Prenez donc le Live-CD de votre choix (par exemple, Debian Live) et démarrez dessus. On va avoir besoin de quelques paquets :

apt-get install ssss qrencode zbar-tools

ainsi que d'un logiciel de manipulation d'images (si il n'y en a pas de fourni sur le Live CD, téléchargez votre préféré). Puis, ouvrez le navigateur du live CD, allez sur offlineaddress.com, et débranchez votre câble Ethernet (et désactivez votre carte wifi, si besoin) pour être sûr de ne plus être connecté. Générez une adresse en utilisant la page du site. Mettez l'adresse de gauche (la chaîne de caractères qui commence par un 1) dans un fichier (disons, ~/publique), et celle de droite (qui commence par un 5) dans un autre fichier (~/privee, par exemple).

On commence par couper les morceaux :

cat privee | ssss-split -t 2 -n 3

ce qui imprime trois lignes commençant par 1, 2 et 3, nos morceaux de clés qu'on évoquait plus haut. Copiez-les quelque part (par exemple, dans trois fichiers morceau1, morceau2 et morceau3). Faites-en des QR codes :

cat morceau1 | qrencode -o "morceau1.png" 
cat morceau2 | qrencode -o "morceau2.png" 
cat morceau3 | qrencode -o "morceau3.png"

et vérifiez qu'ils fonctionnent bien : en en prenant deux au hasard, vous devez être capable de retrouver la clé privée.

zbarimg --raw morceau1.png | tr -s '\n' > partie1 
zbarimg --raw morceau3.png | tr -s '\n' > partie3 
cat partie1 partie3 | ssss-combine -t 2

Ensuite, avec votre logiciel de manipulation d'images, faites une jolie image contenant les QR codes (et les morceaux en format brut, au cas où on en aurait besoin en situation d'urgence sans avoir accès à un appareil permettant de les lire), imprimez-la et coupez-la en trois morceaux, que vous pouvez ensuite protéger et stocker. Imprimez aussi la clé publique, pour savoir à quelle adresse envoyer les Bitcoin que vous voulez stocker de cette façon.

Il ne reste plus qu'à distribuer les différents morceaux à des gens ou des endroits de confiance, et à indiquer sur votre testament quels sont les endroits en question. Le critère de choix principal est « si quelque chose arrive à un des morceaux, il faut qu'on puisse en être averti rapidement ». C'est pourquoi utiliser du papier est important : un disque dur ou une clé USB qui meurt au fond d'un tiroir, ça ne prévient personne et ça ne fait pas de bruit.

Derniers détails

On pourrait améliorer certains points. Utiliser le client Bitcoin officiel au lieu d'un service comme offlineaddress.com est vraisemblablement une bonne idée, par exemple (mais c'est plus compliqué). Par ailleurs, si on est vraiment paranoïaque, on peut faire en sorte que la machine utilisée n'ait jamais été connectée à Internet, pas même avant la génération de l'adresse : un virus pourrait parvenir à truquer le processus… Mais j'ai beau me creuser la tête, je ne vois pas trop (vu comment on génère l'adresse) comment une telle attaque serait possible, et préparer tous les paquets à l'avance est un peu pénible.

Au niveau de la confidentialité, si les morceaux de clé secrètes doivent bien sûr rester secrète, on peut avoir envie que la clé publique le soit aussi. Ça ajoute des complications. On pourrait par exemple utiliser plusieurs adresses (en faisant trois groupes de morceaux), et stocker les adresses publiques en différents endroits, pour faire en sorte que quelqu'un qui en découvre une n'ait qu'une idée partielle de la quantité de Bitcoin stockés…

Au cas où ça soit utile de le préciser : je ne suis pas responsable de ce que vous faites avec ces instructions ; et je ne garantis pas leur sécurité absolue. No warranty for any of this, to the extent permitted by applicable law, etc.

Je n'ai pas de système de commentaires sur ce blog, mais je serai ravi de recevoir des réactions, des critiques ou des demandes de précisions sur ce que j'ai pu écrire. Vous pouvez m'envoyer ce qui vous chante à l'adresse :
se.niatnofsed@neimad.