web-dev-qa-db-fra.com

Gestion des clés de chiffrement des applications Web

En résumé, considérons une application Web qui stocke certaines informations dans une base de données sous forme de données chiffrées. Bien que j'essaie délibérément de garder ce quelque chose de générique, voici quelques hypothèses:

  • Les données cryptées sont uniquement stockées dans la base de données (pas ailleurs). Certains champs d'un enregistrement donné sont cryptés, d'autres non.
  • L'application Web doit écrire les données chiffrées dans la base de données.
  • L'application Web doit pouvoir lire et afficher des données chiffrées. Les données ne sont affichées que dans une section gérée d'authentification et autorisée de l'application.
  • Les données sont des informations sensibles qui doivent être protégées au cas où les données seraient exposées/accessibles (sans les clés *).

Questions:

  • Où/comment stockez-vous la ou les clés utilisées pour le chiffrement? Premièrement, dans un système où les serveurs Web et de base de données sont identiques, comment gérez-vous la clé? Deuxièmement, dans les systèmes où le serveur Web et les serveurs DB sont séparés, comment gérez-vous la clé?
  • Les clés ne sont-elles que des fichiers à autorisation restreinte? Stocké dans un outil/logiciel séparé? J'ai vu mentionner que parfois les clés de cryptage sont également cryptées, mais ne savent pas où cela peut aider.

Je sais que c'est une question de sécurité assez basique et donc s'il y a des ressources qui me manquent, ce serait aussi très, très utile. J'ai passé beaucoup de temps (au fil des ans) à essayer de saisir ces informations sur la base d'informations sur la sécurité des applications Web (OWASP, PCI DSS, etc.), mais souvent ces informations sont très génériques (par exemple, "protéger les données "," crypter les données ") ou très spécifique (" pour crypter quelque chose avec AES faire ceci ... ").

* Je comprends que ce n'est pas une solution de sécurité complète à part entière. Je comprends qu'il existe plusieurs vecteurs pour accéder à ces informations et les décoder. Je reconnais que cela peut être une mauvaise question à cet égard :)

Modifié pour ajouter plus d'informations sur les hypothèses à cette question

47
Rob

Où/comment stockez-vous la ou les clés utilisées pour le chiffrement?

Approche standard si vous utilisez un chiffrement intégré sur quelque chose comme une base de données SQL ou Oracle, la base de données générera une clé de chiffrement et la chiffrera avec une autre clé de protection de clé ou une clé principale. Cela peut être une phrase de passe ou une clé plus longue stockée dans par ex. Fichier .pem.

Il est généralement stocké dans un répertoire restreint auquel seuls root/Administrateur et le compte de service de base de données peuvent accéder. Au lancement de la base de données, la clé est lue et chargée en mémoire. Il est ensuite utilisé pour déchiffrer les clés de chiffrement.

Tout d'abord, dans un système où les serveurs Web et de base de données sont identiques, comment gérez-vous la clé?

La clé est stockée dans un répertoire sur le serveur. Le renouvellement ou la révocation s'effectue généralement via le programme de base de données.

Deuxièmement, dans les systèmes où le serveur Web et les serveurs DB sont séparés, comment gérez-vous la clé?

La clé est stockée localement uniquement sur le serveur de base de données. Une option plus sécurisée consiste à utiliser un module de sécurité matérielle (HSM) dans l'un ou l'autre scénario. Il s'agit d'un périphérique matériel qui est connecté au serveur et utilisé pour stocker la clé plutôt qu'un dossier restreint sur le serveur.

Les clés ne sont-elles que des fichiers à autorisation restreinte? Stockées dans un outil/logiciel séparé? J'ai vu que parfois les clés de cryptage sont également cryptées, mais ne savent pas où cela peut aider.

Restreindre le dossier est acceptable tant que vous gérez l'accès administrateur et surveillez les éléments tels que les connexions non autorisées, les connexions en tant que compte de service, les nouveaux comptes ou les groupes ajoutés avec accès au dossier. Comme mentionné ci-dessus, un HSM est l'option la plus sécurisée si les données que vous protégez et les menaces auxquelles vous êtes confronté en ont besoin.

Généralement, la base de données créera des clés d'instance ou de table, puis les chiffrera avec la clé principale. Il y a un avantage minime à chiffrer davantage la clé principale.

11
Rakkhi

Bien que de bonnes informations aient été fournies dans la réponse précédente, il existe un défaut de conception critique, qui n'est pas vraiment remarqué - mais provient de certaines des hypothèses implicites de la question.

La différence ne doit pas être entre:

  • Application Web et base de données sur le même serveur
  • Application Web et base de données sur différents serveurs
  • chiffrement de l'application ou du db

La conception doit commencer par:

  • Qui a besoin d'accéder aux clés de chiffrement/déchiffrement?

Ou, en fait, encore plus correct:

  • Qui est responsable de la protection de la confidentialité des données?

Qui, à son tour, provient de:

  • Contre quelles menaces essayez-vous de protéger?
    Ou
  • Qui essayez-vous d'empêcher de lire vos données?

Ce n'est que sur la base de ces questions que vous pouvez concevoir un cryptosystème correctement conçu. (Et évitez la poussière de crypto-fée à laquelle @ D.W.a fait référence).

Donc, quelques exemples de scénarios:

  • L'utilisateur doit être responsable du cryptage, empêchant même les administrateurs de l'application de voir les données
  • L'application cliente doit être responsable, sans impliquer l'utilisateur - mais cela doit toujours être fait côté client (par exemple un programme de sauvegarde).
  • Le serveur d'applications chiffre de manière applicative et spécifique les données sélectionnées, dans le cadre de la logique métier (même le dba ne peut pas voir les données)
  • Le serveur de base de données doit chiffrer automatiquement et de manière transparente les données stockées. (Cela protège uniquement contre le vol du fichier db/disque physique, avec des mises en garde ...).

Par souci de simplicité, supposons que le chiffrement doit être effectué côté serveur, la responsabilité incombe au serveur et l'utilisateur final (et l'administrateur) n'a aucune influence sur le chiffrement.

La question principale est donc le chiffrement effectué par le serveur d'applications ou le serveur de base de données? (En fait pas si simple, il y a d'autres options ...)
Cela, comme la plupart des problèmes de sécurité, revient à un compromis:

  • Gérerez-vous vos propres clés, ou préférez-vous que l'infrastructure résume cela automatiquement? (la question d'origine ... plus d'infos ci-dessous ...)
  • Êtes-vous inquiet au sujet des programmes malveillants (ou incompétent programmeurs inexpérimentés)?
  • Êtes-vous inquiet des administrateurs malveillants?
  • Êtes-vous inquiet de l'utilisation non autorisée d'applications?
  • Êtes-vous inquiet à propos d'un accès SQL non autorisé?
  • Êtes-vous inquiet à propos d'un accès direct non autorisé aux fichiers?
  • Êtes-vous préoccupé par le vol physique de disques/serveurs?

Etc. (Notez que certaines des questions ci-dessus ne sont pas pertinentes et ne peuvent pas être résolues par le chiffrement du serveur).


Supposons maintenant que vous ayez pris votre décision, sur la base de ce qui précède, entre le cryptage du serveur d'applications et le cryptage de la base de données.
Notez que si le serveur Web et la base de données sont sur le même serveur ou non, cela n'a presque aucun effet ici - si l'application est en train de crypter, alors elle envoie simplement des données "spéciales" à la base de données, sinon c'est théorique. Cependant, ceci le fait affecte la discussion sur les menaces ci-dessus - certains problèmes sont obsolètes par la conception, certains sont améliorés ...

  • Cryptage du serveur Web/d'applications
    • La clé de chiffrement (EK) que vous utilisez pour chiffrer les données doit être elle-même chiffrée par une clé de chiffrement de clé ( KEK).
    • L'EK chiffré doit être stocké dans un endroit protégé - cela peut être un fichier, une clé de registre, peu importe - l'important est de restreindre l'accès à celui-ci, uniquement à l'utilisateur du serveur d'application (et, peut-être à l'administrateur - voir ci-dessous).
    • La KEK a également besoin d'une protection - c'est un peu plus délicat.
      Si vous êtes sous Windows, vous avez facilement accès à DPAPI - cela fournit une gestion des clés au niveau du système d'exploitation, afin que vous puissiez avoir le système d'exploitation crypter votre KEK et gérer de manière transparente les clés pour vous. (Dans les coulisses, DPAPI repose finalement sur la connaissance du mot de passe de l'utilisateur (dans USER_MODE), donc c'est le dernier point faible d'un vrai secret connu - mais personne d'autre ne devrait savoir le mot de passe du serveur dans la première place, non?)
      Une autre option est le périphérique externe/HSM, discuté plus loin ci-dessous.
    • La KEK a également besoin d'un contrôle d'accès, bien sûr - des listes de contrôle d'accès restrictives et tout cela.
    • Il y a plusieurs raisons pour lesquelles vous souhaitez séparer l'EK de la KEK: vous ne voulez pas crypter d'énormes quantités de données avec une seule clé; si vous devez remplacer la clé, cela devient beaucoup plus facile (rechiffrez simplement l'EK avec la nouvelle KEK); vous pouvez utiliser un chiffrement/stockage plus fort, plus lent et plus complexe sur la KEK; si vous devez être conforme PCI, vous pouvez implémenter la connaissance partagée sur la KEK; et plus.
    • L'EK et la KEK ne doivent pas être stockés à long terme non chiffrés - en fonction de votre plate-forme/langue, cela signifie par exemple ne pas le stocker dans un objet String en .NET ou Java. Au lieu de cela, stockez-le dans des tableaux d'octets modifiables et assurez-vous de toujours en disposer le plus tôt possible.
    • Certains frameworks vont même plus loin et fournissent des objets protégés spécifiques. Par exemple. dans .NET, vous pouvez utiliser les classes System.Security.Cryptography.ProtectedMemory et/ou System.Security.Cryptography.ProtectedData pour protéger les clés, même en mémoire.
  • Cryptage de la base de données
    • Si votre serveur de base de données effectue le chiffrement, cela devient beaucoup plus facile: les tables/champs sont configurés pour chiffrer automatiquement toutes les données qui y sont stockées, la gestion des clés est complètement transparente (à partir du PoV de l'application, pas du DBA), et bientôt.
    • Par exemple, Oracle et MS SQL Server prennent tous les deux en charge le chiffrement intégré automatique. Pour MSSQL, la gestion des clés est complexe, mais similaire à ce que j'ai décrit ci-dessus. Simplifié: il existe un EK, stocké dans la base de données, que le dba peut configurer pour utiliser pour crypter/décrypter les tables ou les champs. Il s'agit d'une table protégée, chiffrée par une KEK, à son tour chiffrée par une KEK de niveau serveur, à son tour chiffrée à l'aide de DPAPI sur le compte de service du MSSQL.
    • Alternativement, MSSQL prend également en charge l'utilisation du chiffrement asynchrone, par ex. stockage de paires de clés publiques/privées - cela peut être utile dans des scénarios spécifiques.
  • Troisième option: stockage de cryptage externe, ou HSM (module de sécurité matériel) . Il peut s'agir d'une appliance matérielle partagée, d'un serveur, d'une carte matérielle ou d'un dongle ... etc.
    • Ces appareils sont conçus pour protéger de manière très sécurisée de petits bits de données - par exemple, votre KEK.
      Encore une fois, une autre raison de séparer l'EK de la KEK - cela vous permettra de crypter et de décrypter efficacement les masses de données avec EK, tout en gérant en toute sécurité la KEK.
    • Le HSM est généralement accessible via un pilote spécial ou une API, il peut également être possible de les brancher au chiffrement de la base de données (selon le produit, etc.).
29
AviD