Cryptage MySQL et gestion des clés

10

Je développe un système intranet local en PHP / MySQL pour gérer nos données clients. Il semble que la meilleure pratique serait de crypter les données sensibles sur le serveur MySQL lors de leur saisie.

Je ne sais pas, cependant, quelle serait la meilleure façon de le faire tout en ayant les données facilement accessibles.

Il semble que la question soit difficile à répondre: où sont stockées les clés? Comment protéger au mieux la clé? Si la clé est stockée sur la machine de chaque utilisateur, comment la protéger si la machine est exploitée? Si la clé est exploitée, comment changer la clé?

Si la clé doit être stockée dans la base de données, comment la protéger là-bas? Comment les utilisateurs y accèderaient-ils?

Tempête Drainage
la source
Le type de cryptage et de stockage de clés dépend du type de scénarios que vous souhaitez éviter. De toute évidence, si votre attaquant obtient un utilisateur root ou une application sur le serveur, il peut utiliser les mêmes routines pour décrypter que votre application utilise. Alors, quel scénario voulez-vous éviter? Quelqu'un qui vole la sauvegarde? Attaque par injection SQL? Autre chose?
Aleksandar Ivanisevic
Merci pour la réponse! Je ne suis pas tellement préoccupé par les sauvegardes. Je suis plus préoccupé par le fait que quelqu'un exploite une machine d'utilisateurs et accède ensuite au site à partir de là soit par injection SQL, soit par brutation des informations d'identification de l'application d'un utilisateur. Je ne suis pas trop préoccupé par la machine elle-même; les informations d'identification pour su sont très solides (je ne me fais pas d'illusion que c'est 100% sécurisé, cependant).
stormdrain

Réponses:

9

Il n'y a pas vraiment de fonctionnalités MySQL intégrées pour gérer les configurations sophistiquées de clés chiffrées. Vous devrez implémenter la majeure partie de la logique de chiffrement dans votre propre code PHP et / ou côté navigateur (javascript?).

Mais vos préoccupations déclarées sont légèrement particulières: il semble que vos seules vraies préoccupations soient une attaque par injection SQL ou force brute (deviner le mot de passe, je suppose) à partir d'un poste de travail client / ordinateur de bureau distant. Cela me fait soupçonner que vous avez déjà prévu d'autres mesures de sécurité non mentionnées et que vous avez analysé les voies de compromis possibles.

  • D'une part, je suppose que vous avez des règles de pare-feu protégeant l'hôte MySQL / PHP contre tout type d'accès à partir des adresses IP des clients distants non approuvés. Si je ne me trompe pas, il est logique que vous ne soyez préoccupé que par les attaques des postes de travail des utilisateurs compromis.

  • En outre, je suppose que vous comprenez que si un attaquant sur l'hôte client distant peut escalader vers les privilèges root / Admin, ou compromettre directement le propre compte de l'utilisateur réel, alors les données du client n'ont aucune protection, quel que soit le cryptage ou toute autre protection. (L'attaquant peut lire les clés où qu'elles soient enregistrées sur le disque, ou les espionner lorsque l'utilisateur réel les saisit à la connexion, et les clés mènent aux données.)

En partant de ces deux hypothèses, il est logique pour nous de conclure que les deux seules menaces pertinentes sont A) la supposition de mot de passe par force brute et B) les tentatives d'injection SQL:

  • Si l'attaquant ne parvient pas à obtenir la clé de l'utilisateur réel, ou s'il souhaite accéder à plus que les données de l'utilisateur réel, il peut essayer des codes de connexion à forçage brut pour l'utilisateur réel ou un autre compte. (En théorie, vous pouvez verrouiller chaque compte sur une adresse IP client distante spécifique, ce qui aiderait également à compartimenter les risques.)
  • Si l'attaquant obtient une clé valide pour l'utilisateur réel, il a un moyen de passer l'écran de connexion (qui est vraisemblablement assez simple pour être sécurisé), jusqu'au ventre mou du code d'application potentiellement bogué. Une injection SQL réussie à partir du contexte réel de l'utilisateur pourrait également lui donner accès aux données d'autres clients.

Maintenant, parlons de la façon dont le chiffrement côté serveur s'applique à ces situations:

  • Le chiffrement côté serveur aide certainement contre la menace d'injection SQL. Si les valeurs de ligne sont chiffrées dans les tables de base de données, l'attaquant ne peut voir que du texte chiffré de charabia des données appartenant à d'autres comptes. La menace est contenue, compartimentée.
  • Brute forçant la devinette des mots de passe, cependant, ne devient pas vraiment plus difficile pour un attaquant confronté au chiffrement côté serveur. Que les clés des utilisateurs soient stockées sur le serveur ou générées sur place à partir du mot de passe, la seule chose qui compte est de savoir si vous avez le bon mot de passe. Soit le serveur décide de vous laisser utiliser la clé stockée valide car il vérifie que votre mot de passe est correct, soit il calcule la clé valide pour vous car votre mot de passe est la bonne entrée pour générer cette clé.

Le chiffrement côté client, en revanche, rend les attaques par mot de passe par force brute non pertinentes. Vous ne pouvez pas forcer une clé correctement construite. Le chiffrement côté client conserve également le même niveau de protection contre l'injection SQL que le chiffrement côté serveur. Le client peut transmettre la clé au serveur à l'ouverture de session, en gardant une copie en mémoire jusqu'à la fin de la session, ce qui alourdit le crypto CPU sur le serveur. Ou bien, le client peut gérer le chiffrement / déchiffrement seul, dans le navigateur. Il y a des hauts et des bas dans les deux techniques:

  • La transmission de sa clé au serveur est beaucoup plus facile à coder et à gérer, et généralement beaucoup plus rapide en raison d'un code cryptographique plus optimisé (compilé C, probablement).
  • Une approche purement côté client offre une sécurité supplémentaire, car même si un attaquant obtient le root sur le serveur, il ne peut toujours pas lire les données chiffrées et il ne pourra jamais les lire. Le seul vecteur d'attaque possible est de compromettre le poste de travail client distant.

Enfin, je vais noter qu'il existe d'énormes inconvénients opérationnels au chiffrement des données dans la base de données. Étant donné que les représentations de données chiffrées sont essentiellement des modèles aléatoires, les fonctionnalités de base de données telles que l'indexation, les jointures, etc. ne fonctionneront pas. Le client assume une énorme charge logique et peut perdre beaucoup des avantages que les fonctionnalités de base de données apportent normalement.

Ryan B. Lynch
la source
1
Hou la la! Réponse étonnante et approfondie; Merci beaucoup. Au cours des derniers jours, j'ai envisagé certaines options et j'ai décidé d'essayer de mettre en œuvre une solution côté client comme vous l'avez suggéré. Idéalement, les clés seront stockées sur des clés USB qui ne seront montées que lorsqu'un utilisateur travaille sur le système (la sécurité physique est très stricte) et la clé conservée en mémoire uniquement pendant la durée de la session. L'idée étant que les clés ne seront accessibles au système que pendant les heures de travail lorsque je serai là pour surveiller le trafic, etc.
stormdrain
2

Vous voudrez peut-être regarder ezNcrypt , qui utilise ecryptfs, les contrôles d'accès et la gestion des clés pour fournir une sécurité et des performances élevées pour le chiffrement Linux des bases de données MySQL et d'autres processus. Non, je ne travaille pas pour eux.

Dan
la source
2

Vous pouvez utiliser Scytale. Il s'agit d'un proxy cryptographique NoSQL pour les SGBD et les applications Web modernes. Prend en charge le cryptage multi-destinataires et de groupe. Chargé avec un cryptosystème RSA / AES puissant. Il est également 100% gratuit et open-source.

https://bitbucket.org/maximelabelle/scytale

Maxime Labelle
la source