Journal Hutch, gestionnaire de mots de passe

20
15
déc.
2017

Après avoir fini Glewlwyd et branché Angharad dessus, il me fallait un autre projet pas trop gros pour utiliser l'authentification unique, parce que un seul service qui utilise ton authentification unique, c'est un peu trop overkill on va dire.

Je ne voulais pas faire mon serveur de streaming tout de suite, parce que je savais que ca allait être long. Je voulais un projet moins gros, sur lequel je pouvais me faire la main coté serveur de ressource, mais utile, et puis j'avais envie d'essayer Angular2.

Les services que j'utilise sur le net font que, comme beaucoup d'entre nous, j'ai une tétrachiée de mots de passes. Je me refuse à utiliser toujours le même, c'est dur à retenir ou alors ca le rend trop facile à deviner. Bref, c'est pas la joie.

Il existe déjà des gestionnaires de mots de passes comme Keepass ou des services Web qui proposent de faire ca dans les nuages comme 1password, mais je n'avais pas vu de gesionnaire de mots de passes qui soit libre, dont on peut installer sa propre instance, disponible à distance, et si possible pas en Java ou NodeJS.
De plus l'API Web Cryptography est maintenant disponible dans la plupart des navigateurs modernes.

C'était donc une bonne occasion de combiner tout ca pour faire mon gestionnaire de mot de passe qui ferait les choses suivantes:
- Encodage/Décodage uniquement coté client, le serveur ne stocke que des blobs chiffrés qu'il sera incapable de décoder
- Sous forme d'API Rest pour le serveur, et écrit en Angular2/TypeScript pour le client web
- Permet de stocker des données liées à plusieurs services différents: url, nom d'utilisateur, mot de passe, questions secrètes, fichiers (de clé privée par exemple), ou autres informations que tu jugeras utile pour le service
- Permet de copier le mot de passe ou autre info dans le presse-papier, sans que tu n'aies à le voir, en cliquant sur un bouton
- Permet de générer aléatoirement des mots de passe selon des critères que tu lui aura défini: caractères, chiffres, majuscule/minuscule, caractères spéciaux, etc.
- Permet de générer aléatoirement des réponses à des questions secrètes, pour éviter de deviner ces réponses par ingénierie sociale, la réponse aléatoire est composée de deux mots piochés dans un fichier de mots courant dans la langue que tu utilises dans l'application web
- Utilisable sur ordinateur, tablette, téléphone intelligent, parce que j'ai pas envie de faire 10000 clients différents (vive Bootstrap!)

Je l'ai appelé Hutch, c'est un nom que j'ai trouvé qui permettait de nommer un coffre au moyen-âge, mais je me rappelle plus où j'ai vu ca. Puis si tu tapes "Hutch" dans Google images, tu vas voir des cages à lapin mais tant pis…

On peut créer un ou plusieurs coffres qui contiendront des secrets. Chaque coffre a son propre mot de passe, et le mot de passe permet de débloquer tous les secrets du coffre. Comme ca tu peux avoir un coffre pour le boulot, un pour les trucs persos, un pour ton association, etc. Si tu te fais piquer le mot de passe d'un coffre, les autres ne sont pas impactés par les éventuelles fuites.

Évidemment si tu perds un mot de passe de coffre, le serveur ne pourra rien pour toi, pas de mail pour réinitialiser son coffre ou quoi, que dalle, c'est perdu.
Pour pallier ca, il y a plusieurs barrières de sécurité, mais qui peuvent ouvrir des brêches énormes:
- Exporter la clé principale de ton coffre, l'export peut être protégé par un mot de passe ou pas
- Exporter un secret ou tous les secrets d'un coffre dans un fichier, l'export peut être protégé par un mot de passe ou pas

Enfin, pour que ce ne soit pas trop pénible à utiliser non plus, tu peux garder un coffre toujours ouvert sur une machine si tu le souhaites. Comme ca tu n'as pas à retaper ton mot de passe à chaque fois, mais faut faire ca sur une machine dont tu est sûr de chez sûr.

Il est disponible sur GitHub à cette adresse: Hutch

Il est en GPL V3 pour la partie serveur, écrite en C, et Affero GPL pour la partie client Web, écrite en Angular2.

Épilogue, Angular2

Avec le recul, Angular2 j'en suis revenu. C'est cool, moins fouilli que AngularJS, mais c'est pas non plus la panacée. Il se base sur TypeScript qui, malgré le fait que ce soit développé par Microsoft, est quand même assez chouette. Sauf que TypeScript souffre encore beaucoup d'être pas fini. En l'occurence, au moment où je programmais Hutch, Typescript n'intégrait pas l'API Web Crypto, ce qui fait que j'ai du faire des pirouettes pour que ca soit propre dans mon code…
Puis, entre le moment où j'ai commencé le projet, et le moment où je l'ai fini, Angular2 est devenu Angular3, puis 4. Maintenant, c'est Angular.IO tout court. En soi c'est pas grave, mais les plugins autour d'Angular, suivent mal la cadence, ou justement trop bien, et certains refusaient carrément de s'installer sur mon "vieux" Angular2…

  • # En C quoi...

    Posté par  (site web personnel, Mastodon) . Évalué à 5.

    et si possible pas en Java ou NodeJS.

    Après avoir lu cette phrase, je me suis dis, chouette, il va proposer un truc plus simple à déployer, et utilisable partout ?

    J'ai déchanté quand j'ai lu "écrite en C" puis je me suis effondré quand je suis aller voir les sources : il faut aller chercher plusieurs libs dépendantes à droite et à gauche, lancer les compilations une à une.. Il n'y a même pas un beau makefile qui te fasse tout ça sans effort. Et je n'ai pas vu de paquets debian (ou pour une autre distro) quelque part.

    Très sérieusement, ton idée de projet fait vraiment envie, parce qu'on manque de solutions de ce genre, et il a l'air bien architecturé (chiffrage coté client etc). Mais l'avoir fait en C, c'est juste un barrière énorme de mon point de vue, à la diffusion et aux contributions. Laissons le C aux applications systèmes, merci, et faisons des applications web avec des technologies faites pour ça. (Tu aurais fait ça en Rust encore, j'aurais été plus indulgent…).

    Et cela nécessite d'avoir un serveur dédié. Ça ne cible que les geeks qui ont les moyens donc. Dommage.

    • [^] # Re: En C quoi...

      Posté par  (site web personnel) . Évalué à 4.

      J'avoue, la partie serveur d'API n'est jamais qu'un conteneur de blobs chiffrés, si j'ai choisi le C c'est parce que c'est mon langage de prédilection coté serveur, et donc que je fais ca plus vite.
      Après, l'API est décrite dans ce document donc si tu veux le réimplémenter dans ton langage ou environnement préféré, tu peux toujours.

  • # Existant

    Posté par  . Évalué à 10.

    mais je n'avais pas vu de gesionnaire de mots de passes qui soit libre, dont on peut installer sa propre instance, disponible à distance, et si possible pas en Java ou NodeJS

    Tu n’as pas bien cherché alors:

    https://www.passbolt.com
    https://bitwarden.com
    https://github.com/clipperz/password-manager
    https://github.com/ehazlett/locksmith
    http://indefero.soutade.fr/p/gpass/
    https://github.com/sloonz/wkr/

    Sinon, pourquoi utiliser SHA256 (sans salt en plus !) pour dériver une clé AES à partir d’un mot de passe, alors que PBKDF2 est fait pour ça et dispo dans WebCrypto ?

    • [^] # Re: Existant

      Posté par  . Évalué à 4.

      Sans oublier "the standard unix password manager" https://www.passwordstore.org/

    • [^] # Re: Existant

      Posté par  (site web personnel) . Évalué à 2.

      J'en ai vu quelques-uns que tu mentionnes mais pour faire de l'auto-hébergement depuis très longtemps maintenant, et à cause de mon coté old-school qui aime les micro-services, j'ai plus trop envie d'installer des services si je ne suis pas capable de mettre les mains dans le cambouis, ou si y'a pas un paquet Debian officiel.

      Ce n'est en aucun cas un jugement de valeur sur les logiciels que tu cites, d'ailleurs ils font sûrement mieux que Hutch, sauf que Hutch s'installe et se maintient très bien pour l'utilisation que je souhaite avoir.

      Sinon, pourquoi utiliser SHA256 (sans salt en plus !) pour dériver une clé AES à partir d’un mot de passe, alors que PBKDF2 est fait pour ça et dispo dans WebCrypto ?

      Bonne question, j'ai appris WebCrypto tout seul et j'ai pas du le voir ou pas du faire attention dans les tutos que PBKDF2 pouvait servir à ca.
      Dans mon cas, le mot de passe du coffre est hashé en SHA256 pour avoir une clé de 256 bits qui sert de clé de chiffrement AES, parce que AES ne prendra pas de clé de chiffrement qui n'est pas de 256 bits.
      Par contre ta remarque est intéressante, je regarderai PBKDF2. Si tu as un exemple de code à me donner ou même un pull request à me proposer, n'hésite pas!

      • [^] # Re: Existant

        Posté par  (site web personnel) . Évalué à 4.

        Si tu n'es pas très à l'aise en crypto, je te recommande fortement de reprendre le mode de fonctionnement d'un gestionnaire de mots de passe existant qui a fait ses preuves.

        Pour bitwarden, il existe une documentation de l'API (écrite par un tiers) qui parle des questions crypto : https://github.com/jcs/bitwarden-ruby/blob/master/API.md. Ça pourrait être cool d'avoir une API compatible avec bitwarden.

    • [^] # Re: Existant

      Posté par  (site web personnel) . Évalué à 4.

      Il y a également Buttercup. C'est récent, mais ça a déjà l'air d'être assez joli et pratique à utiliser.

  • # NodeJS

    Posté par  (site web personnel) . Évalué à 4.

    Il existe déjà des gestionnaires de mots de passes comme Keepass ou des services Web qui proposent de faire ca dans les nuages comme 1password, mais je n'avais pas vu de gesionnaire de mots de passes qui soit libre, dont on peut installer sa propre instance, disponible à distance, et si possible pas en Java ou NodeJS.

    Pourquoi pas en NodeJS  ?

    Pour +/- le même besoin j'ai créé passprotect : https://passprotect.shadoware.org avec les sources dispo ici : https://github.com/phoenix741/passprotect-server

    L'implémentation est par contre faite en NodeJS (il existe une image docker mais il n'est pas obligatoire de l'utiliser).

    Le chiffrage, déchiffrage est fait coté client, ce qui permet de ne pas faire confiance au serveur :)

    • [^] # Re: NodeJS

      Posté par  . Évalué à 2.

      Le chiffrage, déchiffrage est fait coté client par du code envoyé par le serveur, ce qui permet de ne pas faire confiance au serv…euh, non, rien.

      • [^] # Re: NodeJS

        Posté par  (site web personnel) . Évalué à 1.

        D'où l'utilité de maîtriser le code du serveur et même de monter sa propre instance.

      • [^] # Re: NodeJS

        Posté par  . Évalué à 2. Dernière modification le 21 décembre 2017 à 12:58.

        Tu peux très bien utiliser du code envoyé par un serveur auquel tu ne fais pas confiance, tant que tu obtiens la signature du code par un canal de confiance.

        https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity

        • [^] # Re: NodeJS

          Posté par  (site web personnel) . Évalué à 2.

          Le concept est intéressant, mais il ne s'applique pas dans notre cas.

          D'après la documentation que tu pointes, on obtient quelque chose comme ça :

          <script src="https://example.com/example-framework.js"
                  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
                  crossorigin="anonymous"></script>

          Le navigateur va donc vérifier l'intégrité de example-framework.js qui provient de example.com. Hors, dans le cas d'un gestionnaire de mot de passe, c'est le serveur principal qui génère la page HTML avec la balise script. Il peut donc forger à la volée la balise integrity.

          Par contre, c'est une fonctionnalité intéressante dans le cas où on rapatrie des frameworks externes (jquery, Google…).

      • [^] # Re: NodeJS

        Posté par  (site web personnel) . Évalué à 2.

        C'est vrai quelque soit la techno du serveur. Ce dernier ne sert que les fichiers dont il a envie, le serveur port être écrits en c, PHP, ou go, il peut très bien servir du js vérolé.

        Du coup je ne comprends toujours pas le pourquoi pas un serveur en NodeJS

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.