web-dev-qa-db-fra.com

Dois-je chiffrer des données de formulaire sensibles avec JavaScript sur le client?

Ce n'est en aucun cas un remplacement pour HTTPS, donc s'il vous plaît ne présumez pas que c'est pourquoi je pose cette question. J'explore et je suis curieux. Je suis à la recherche de commentaires d'experts à ce sujet, et je ne sais pas trop où je dois poser cette question.

D'accord, disons que j'envoie des informations très sensibles (informations bancaires par exemple). Et je veux aller plus loin pour le protéger.

Avec JavaScript, je chiffrerais les données du formulaire lors de leur soumission. Ensuite, je le décrypterais sur le serveur (back-end).

  • La première option consisterait à utiliser le chiffrement asymétrique seul. Chiffrez les données du formulaire lors de la soumission, avec la clé publique. Et comme il est public, il ne peut pas faire de mal au client de le savoir. Ensuite, sur le serveur, déchiffrez les données avec la clé privée. Ce qui est évidemment privé, et seul le serveur le sait.

  • Beaucoup d'algorithmes asymétriques sont vraiment lents d'après ce que j'ai entendu, et peuvent être assez limités en termes de chiffrement (RSA par exemple). Et le cryptage hybride? Chiffrez les données du formulaire avec un chiffrement symétrique (clé aléatoire générée à chaque fois), puis chiffrez la clé symétrique avec avec la clé asymétrique publique. Envoyez la clé symétrique avec les données. Déchiffrez la clé avec la clé privée, utilisez la clé pour déchiffrer les données.

Qu'est-ce que tu penses? Je suis un peu perdu quant à ce qui serait mieux. Et comment s'y prendre.

5
user10103279

Le meilleur scénario ici est que vous perdez votre temps. Généralement, le chiffrement côté client au-dessus de HTTPS dans une application Web représente beaucoup de travail, mais il n'offre aucune sécurité supplémentaire.

Le but d'une couche cryptographique supplémentaire serait de se protéger contre un MITM qui a en quelque sorte réussi à casser le cryptage TLS. Mais un attaquant qui l'a fait pourrait facilement modifier simplement la source JS de votre crypto supplémentaire, en le désactivant simplement. Donc, cela ne serait utile que contre un MITM passif qui a craqué TLS, et ce n'est vraiment pas un modèle de menace qui vaut la peine d'investir beaucoup d'énergie contre.

Notez également que les limitations de nombreux navigateurs (Opera Mini, IE9) permettant de générer des nombres aléatoires sécurisés compliquent le chiffrement côté client. Vous ne devriez jamais compter sur Math.random pour tout ce qui concerne la cryptographie.

Vous devez concentrer votre énergie là où elle a un impact maximal. Au lieu d'implémenter votre propre crypto, assurez-vous que vous utilisez correctement la bonne crypto que vous obtenez gratuitement avec HTTPS. Si vous êtes préoccupé par les attaques MITM, il serait beaucoup mieux de se pencher sur le HSTS et le préchargement.

8
Anders

Probablement pas, mais ...

La plupart des informations décrites dans la réponse @Anders étaient correctes et devraient être reconnues comme la réponse correcte.

Si nous supposons que vous effectuez le chiffrement spécifiquement pour la session client-serveur en cours, il n'y aura aucun avantage supplémentaire par rapport à l'utilisation de HTTPS.

Cependant, puisque vous avez expliqué que vous ne cherchez pas d'alternative au HTTPS, je vais supposer que vous explorez l'un des scénarios suivants:

  1. Vous créez une architecture de serveur à plusieurs niveaux, où vous souhaitez uniquement que les serveurs avec des autorisations élevées puissent lire les données sensibles.

  2. Vous voulez pouvoir stocker les données au repos dans une base de données, mais vous voulez seulement certains de vos serveurs pour pouvoir les lire.

  3. En fait, vous voulez juste un chiffrement côté client, où le serveur ne peut pas le lire, mais peut le stocker.


Caveat Emptor

Ces trois scénarios reposent sur l'hypothèse que vous pouvez faire confiance au code du serveur dans une certaine mesure. (Cela pourrait fonctionner dans des organisations structurées qui ont une révision importante du code).


Méthodes traditionnelles

L'option 1 pourrait être implémentée de manière traditionnelle en activant CORS et en permettant au client de communiquer avec votre serveur "élevé". Cependant, cela vous oblige à ouvrir votre serveur "élevé" à Internet.

Cela implique généralement la tokenisation et est une approche utilisée par de nombreux processeurs de paiement.

L'option 2 pourrait être implémentée côté serveur, en chiffrant symétriquement avant d'insérer les données dans la base de données.


Méthodes non traditionnelles (pour le bien de l'éducation)

Supposons que vous ayez un mélange unique d'options 1 et 2, ou que vous souhaitiez explorer l'option 1 sans ouvrir le serveur au Web ouvert.

Oui, vous pouvez utiliser un crypto-système hybride (asymétrique + symétrique) pour crypter efficacement les données que seuls des serveurs spécifiques pourraient décrypter. L'implémentation d'un tel cryptosystème est un défi et nécessite des connaissances cryptographiques étendues pour fonctionner correctement.

Pour l'option 3, vous pouvez chiffrer/déchiffrer symétriquement côté client pour protéger les données utilisateur. Cela nécessiterait probablement qu'une variable soit stockée dans localStorage (pour plus de commodité), ce qui comporte des risques (il est plus facile de masquer le code qui le gratte).

Ces approches pourraient aider à rendre plus difficile pour les employés d'une organisation structurée de voler des données utilisateur. Mais cela ne fonctionne que si le mécanisme de cryptage des données ne peut pas être altéré ou si les informations d'identification ne peuvent pas être volées.

Le cryptage ne sera pas une solution miracle dans tous les scénarios que j'imagine. Il peut atténuer un certain nombre de vecteurs d'attaque, mais il ne les résoudra pas tous. Vous auriez besoin d'un examen approfondi du code.

0