[Disclaimer: Je sais, si vous connaissez la crypto, vous êtes probablement sur le point de me dire pourquoi je ne le fais pas correctement - j'ai déjà fait assez de recherches sur Google pour savoir que cela semble être la réponse typique.]
Supposons ce qui suit: vous avez une autorité centrale qui souhaite émettre des cookies de connexion pour un domaine donné. Sur ce domaine, vous ne faites pas nécessairement confiance à tout le monde, mais vous avez quelques points finaux clés qui devraient pouvoir lire le cookie. J'en dis quelques-unes, mais dans la pratique, ce nombre de partenaires "de confiance" peut être important. Le cookie ne contient pas beaucoup d'informations - un nom d'utilisateur, un horodatage, une date d'expiration, un nombre aléatoire. Pour des raisons de performances, il devrait rester modeste bien sûr, même après le cryptage (dans des limites raisonnables). Maintenant, il y a deux problèmes de sécurité:
1) Nous ne faisons pas confiance à tous les serveurs Web de ce domaine contenant des données utilisateur. Pour cette raison, la possibilité de lire le cookie doit être limitée à ces partenaires de confiance. 2) Même si nous faisons confiance à ces partenaires pour protéger les données de nos utilisateurs, nous souhaitons tout de même que le point central d'autorité soit infalsifiable (là encore, dans des limites raisonnables).
Maintenant, si nous générons une clé RSA privée pour l'autorité et la gardons secrète, et distribuons la clé publique uniquement aux "partenaires de confiance", nous devrions être en mesure de chiffrer avec la clé privée et de la rendre lisible par quiconque possédant la clé publique. . Ce sur quoi je ne suis pas sûr, c'est s'il serait toujours nécessaire de signer le message ou si l'acte de déchiffrement constituait la preuve qu'il avait été généré avec la clé privée. Est-ce une façon pour ce système d’être meilleur ou pire que de diffuser une clé symétrique à toutes les parties impliquées et de l’utiliser pour chiffrer, tout en utilisant la clé privée uniquement pour signer? Et bien sûr, n'hésitez pas à me dire toutes les façons dont cette idée est stupide, mais gardez à l'esprit que des arguments pratiques seront probablement plus convaincants que de ressasser Alice et Bob.
Oh, et les indicateurs de mise en œuvre seraient les bienvenus, même si on peut trouver les bases sur Google, s’il ya des "pièges" impliqués qui seraient utiles!
Vous devez utiliser un schéma de signatures numériques, ou un autre mécanisme visant à résoudre le problème intégrité de votre scénario.
Le cryptage lui-même ne suffit pas. Comment savez-vous que le message déchiffré est ce qu'il devrait être? que se passe-t-il lorsque vous décryptez un cookie crypté avec la mauvaise clé? ou juste des données sans signification? Eh bien, vous pourriez juste obtenir un cookie qui a l'air valide! (les horodatages sont dans la plage que vous considérez comme valide, le nom d'utilisateur est légal, le nombre aléatoire est ... euh ... un nombre, etc.).
Dans la plupart des algorithmes de chiffrement asymétriques que je connais, il n’existe pas de validation intégrée. Cela signifie que décrypter un message avec la mauvaise clé ne "échouera" pas - cela vous donnera uniquement un texte en clair erroné, que you doit distinguer d'un texte en clair valide. C’est là que l’intégrité commence à jouer, le plus souvent - en utilisant des signatures numériques.
BTW, RSA a longtemps été étudié et a plusieurs "pièges", donc si vous envisagez de le mettre en œuvre à partir de zéro, vous feriez mieux de lire à l'avance sur la façon d'éviter de créer des clés "relativement faciles à casser".
Nate Lawson explique ici et ici pourquoi vous ne pouvez pas utiliser la clé publique de manière sécurisée comme clé de déchiffrement secrète (c'est un point ne vous sentez pas mal!).
Utilisez simplement votre clé publique pour vous authentifier, et une clé symétrique distincte pour le secret.
J'ai suffisamment lu sur les attaques intéressantes contre les systèmes à clé publique, et notamment la RSA, pour être absolument d'accord avec cette conclusion:
Les cryptosystèmes à clé publique et RSA, en particulier, sont extrêmement fragiles. Ne Ne les utilisez pas différemment de ce qu'ils Ont été conçus.
(Cela signifie: chiffrer avec la clé publique, signer avec la clé privée et tout le reste joue au feu.)
Addendum:
Si vous souhaitez réduire la taille des cookies générés, envisagez d'utiliser ECDSA plutôt que RSA pour générer les signatures. Les signatures ECDSA sont considérablement plus petites que les signatures RSA d'un facteur de sécurité équivalent.
En cryptographie, vous êtes ce que vous savez. Dans votre scénario, vous avez une autorité centrale capable d'émettre vos cookies et vous souhaitez qu'aucune autre entité ne puisse en faire autant. L’autorité centrale doit donc "connaître" certaines données privées. En outre, vous souhaitez que les "serveurs Web de confiance" puissent accéder au contenu des cookies, et vous ne voulez pas que quiconque lise les cookies. Ainsi, les "serveurs Web de confiance" doivent également disposer de leurs propres données privées.
La manière habituelle serait que l'autorité applique une signature numérique sur les cookies et que les cookies soient cryptés avec une clé connue des serveurs Web sécurisés. À quoi pensez-vous ressemble à ceci:
Bien qu'un tel système puisse fonctionner, j'y vois les problèmes suivants:
Le problème de la confidentialité et de l'intégrité vérifiable dans le même type est actuellement à l'étude. Vous pouvez rechercher signcryption . Il n'y a pas encore de norme établie.
Fondamentalement, je pense que vous serez plus heureux avec un design plus classique, avec des signatures numériques utilisées uniquement pour la signature et un cryptage (symétrique ou asymétrique) pour la partie relative à la confidentialité. Cela vous permettra d'utiliser les bibliothèques existantes, avec le moins de code possible.
Pour la partie signature, vous pouvez utiliser DSA ou ECDSA: elles donnent des signatures beaucoup plus courtes (généralement 320 bits pour une signature DSA de sécurité équivalente à une signature RSA 1024 bits). Du point de vue des autorités centrales, ECDSA permet également de meilleures performances: sur mon PC, utilisant un seul cœur, OpenSSL traite plus de 6500 signatures ECDSA par seconde (dans la courbe NIST P-192) et "seulement" 1145 signatures RSA par seconde. seconde (avec une clé de 1024 bits). Les signatures ECDSA se composent de deux entiers de 192 bits, à savoir 384 bits à coder, tandis que les signatures RSA ont une longueur de 1024 bits. ECDSA dans P-192 est considéré au moins aussi fort et probablement plus fort que RSA-1024.
Les clés publiques sont par définition publiques. Si vous chiffrez avec une clé privée et que vous déchiffrez avec une clé publique, vous n'êtes pas à l'abri des regards indiscrets. Tout ce qu'il dit: "ces données proviennent de la personne X qui détient la clé privée X" et tout le monde peut le vérifier, car l'autre moitié de la clé est publique.
Qu'est-ce qui empêche quelqu'un de confiance de placer la clé publique X sur un serveur auquel vous ne faites pas confiance?
Si vous souhaitez une ligne de communication sécurisée entre deux serveurs, tous les serveurs de confiance doivent posséder leur propre paire de clés publique/privée. Nous allons dire paire de clés Y pour un tel serveur.
Le serveur X peut alors chiffrer un message avec la clé privée X et la clé publique Y. Cela dit: "le serveur X a envoyé un message que seul Y pouvait lire et que Y pouvait vérifier qu'il provenait de X."
(Et ce message devrait contenir une clé symétrique de courte durée, car le cryptage de clé publique prend beaucoup de temps.)
C'est ce que fait SSL. Il utilise la crypto à clé publique pour configurer une clé de session.
Cela étant dit, utilisez une bibliothèque. Ce truc est facile à bousiller.
La réponse à votre question "l'acte de déchiffrement serait-il la preuve qu'il a été généré avec la clé privée" , la réponse est oui si le destinataire peut effectuer une simple validation des données. Disons que vous avez "Nom d'utilisateur: John, horodatage: <numéro>, expiration: jj/mm/aaaa". Maintenant, si une mauvaise clé publique est utilisée pour déchiffrer, la probabilité que vous obteniez "Nom d'utilisateur: <quelques lettres>, horodatage: <uniquement des chiffres>, expiration: ??/??/????" est zéro. Vous pouvez valider à l'aide d'une expression régulière (regex) du type "Nom d'utilisateur: [a-zA-Z] +, horodatage: [0-9] +, expiration: ...." et échouez. La validation échoue. Vous pouvez même vérifier si le jour est compris entre 1 et 31 et le mois entre 1 et 12, mais vous ne pourrez pas l'utiliser, car l'expression rationnelle échouera généralement sous "Nom d'utilisateur:" si une mauvaise clé publique est utilisée. Si la validation réussit, vous devez toujours vérifier l'horodatage et vous assurer que vous n'avez pas d'attaque par rejeu.
Cependant, considérez ce qui suit:
Si vous souhaitez toujours utiliser cette approche et êtes en mesure de distribuer la clé publique only aux "partenaires de confiance", vous devez générer une clé de session aléatoire (c'est-à-dire une clé symétrique), puis la chiffrer à l'aide de la clé privée. et envoyer à tous les destinataires qui ont la clé publique. Vous chiffrez ensuite le cookie à l'aide de la clé de session. Vous pouvez changer la clé de session périodiquement. Plus rarement, vous pouvez également modifier la clé publique: vous pouvez générer une nouvelle paire de clés publique/privée, chiffrer la clé publique avec la clé de session et l'envoyer à tous les destinataires.
Je présume que vous faites confiance aux "partenaires de confiance" pour décrypter et vérifier le cookie, mais vous ne voulez pas qu'ils puissent générer leurs propres cookies? Si cela ne pose pas de problème, vous pouvez utiliser un système beaucoup plus simple: distribuez une clé secrète à toutes les parties et utilisez-la pour chiffrer le cookie et générer un HMAC. Pas besoin de crypto à clé publique, pas besoin de plusieurs clés.
En guise d'alternative à votre approche de distribution de clés, qui peut ou non convenir à votre application, envisagez d'utiliser Kerberos , qui utilise le chiffrement à clé symétrique, un serveur bastion hautement protégé contrôlant tout le un ensemble intelligent de protocoles (voir le protocole Needham-Schroder )