342 votes

RS256 vs HS256 : quelle est la différence ?

J'utilise Auth0 pour gérer l'authentification dans mon application web. J'utilise ASP.NET Core v1.0.0 et Angular 2 rc5 et je ne m'y connais pas beaucoup en authentification/sécurité en général.

Dans le Docs Auth0 pour ASP.NET Core Web Api Dans le cas de JWT, il y a deux choix pour l'algorithme JWT : RS256 et HS256. C'est peut-être une question stupide mais :

Quelle est la différence entre RS256 et HS256 ? Quels sont les cas d'utilisation (le cas échéant) ?

1 votes

Voir aussi les réponses sur l'échange de piles de sécurité Algorithmes recommandés pour JWT

559voto

Nico Sabena Points 2861

Les deux choix font référence à l'algorithme utilisé par le fournisseur d'identité pour signe le JWT. La signature est une opération cryptographique qui génère une "signature" (partie du JWT) que le destinataire du jeton peut valider pour s'assurer que le jeton n'a pas été falsifié.

  • RS256 (Signature RSA avec SHA-256 ) est un algorithme asymétrique Le fournisseur d'identité possède une clé privée (secrète) utilisée pour générer la signature, et le consommateur du JWT reçoit une clé publique pour valider la signature. Étant donné que la clé publique, contrairement à la clé privée, n'a pas besoin d'être conservée de manière sécurisée, la plupart des fournisseurs d'identité la mettent à la disposition des consommateurs pour qu'ils puissent l'obtenir et l'utiliser (généralement via une URL de métadonnées).

  • HS256 ( HMAC avec SHA-256), en revanche, implique la combinaison d'une fonction de hachage et d'une clé (secrète) partagée entre les deux parties, utilisée pour générer le hachage qui servira de signature. Comme la même clé est utilisée à la fois pour générer la signature et pour la valider, il faut veiller à ce que la clé ne soit pas compromise.

Si vous développez l'application qui utilise les JWT, vous pouvez utiliser HS256 en toute sécurité, car vous aurez le contrôle sur les personnes qui utilisent les clés secrètes. Si, en revanche, vous ne contrôlez pas le client, ou si vous n'avez aucun moyen de sécuriser une clé secrète, RS256 sera plus adapté, puisque le consommateur n'a besoin de connaître que la clé publique (partagée).

Comme la clé publique est généralement disponible à partir des points de terminaison des métadonnées, les clients peuvent être programmés pour récupérer la clé publique automatiquement. Si c'est le cas (comme c'est le cas avec les bibliothèques .Net Core), vous aurez moins de travail à faire pour la configuration (les bibliothèques iront chercher la clé publique sur le serveur). Les clés symétriques, en revanche, doivent être échangées hors bande (en assurant un canal de communication sécurisé) et mises à jour manuellement en cas de renouvellement de la clé de signature.

Auth0 fournit des points d'accès aux métadonnées pour les protocoles OIDC, SAML et WS-Fed, où les clés publiques peuvent être récupérées. Vous pouvez voir ces points de terminaison dans les "Paramètres avancés" d'un client.

Le point de terminaison des métadonnées de l'OIDC, par exemple, prend la forme suivante https://{account domain}/.well-known/openid-configuration . Si vous naviguez vers cette URL, vous verrez un objet JSON avec une référence à https://{account domain}/.well-known/jwks.json qui contient la (ou les) clé(s) publique(s) du compte, représentée(s) sous la forme d'un fichier de type Jeu de clés Web JSON .

Si vous regardez les échantillons RS256, vous verrez que vous n'avez pas besoin de configurer la clé publique où que ce soit : elle est récupérée automatiquement par le framework.

57 votes

NB lors de l'utilisation de rs256 - il y a (ou il y avait) une risque de sécurité dans de nombreuses bibliothèques qui permettaient au jeton de déterminer l'algorithme à utiliser. En fait, l'attaquant pouvait utiliser la clé publique rs256 avec un encodage hs256 pour faire croire qu'il s'agissait de la clé secrète. Assurez-vous donc que votre bibliothèque n'a pas ce comportement !

10 votes

Une petite correction, "HS256 (HMAC avec SHA-256), d'autre part, est un algorithme symétrique" - HMAC n'utilise pas d'algorithme à clé symétrique (qui vous permettrait de crypter et décrypter la signature par sa définition). Il utilise une fonction de hachage cryptographique et une clé cryptographique secrète en dessous. HMAC . Ce qui implique le calcul du hash (fonction à sens unique) sur le message avec une clé secrète jointe.

2 votes

Exemple avec Google : Aller sur accounts.google.com/.well-known/openid-configuration et regardez jwks_uri ; il vous renvoie à googleapis.com/oauth2/v3/certs où vous pouvez trouver des clés. Il suffit ensuite de récupérer la bonne clé par son petit.

120voto

Charlie H Points 2538

En cryptographie, deux types d'algorithmes sont utilisés :

Algorithmes symétriques

Une seule clé est utilisée pour chiffrer les données. Une fois cryptées avec la clé, les données peuvent être décryptées à l'aide de la même clé. Si, par exemple, Marie crypte un message à l'aide de la clé "mon-secret" et l'envoie à Jean, celui-ci pourra décrypter le message correctement avec la même clé "mon-secret".

Algorithmes asymétriques

Deux clés sont utilisées pour crypter et décrypter les messages. Alors qu'une clé (publique) est utilisée pour crypter le message, l'autre clé (privée) ne peut être utilisée que pour le décrypter. Ainsi, Jean peut générer des clés publiques et privées, puis envoyer uniquement la clé publique à Marie pour chiffrer son message. Le message ne peut être décrypté qu'à l'aide de la clé privée.

Scénario HS256 et RS256

Ces algorithmes ne sont PAS utilisés pour crypter/décrypter des données. Ils sont plutôt utilisés pour vérifier l'origine ou l'authenticité des données. Lorsque Marie doit envoyer un message ouvert à Jhon et que celui-ci doit vérifier que le message provient bien de Marie, on peut utiliser HS256 ou RS256.

HS256 peut créer une signature pour un échantillon donné de données en utilisant une seule clé. Lorsque le message est transmis avec la signature, le destinataire peut utiliser la même clé pour vérifier que la signature correspond au message.

Le RS256 utilise une paire de clés pour faire la même chose. Une signature ne peut être générée qu'en utilisant la clé privée. Et la clé publique doit être utilisée pour vérifier la signature. Dans ce scénario, même si Jack trouve la clé publique, il ne peut pas créer un faux message avec une signature pour se faire passer pour Mary.

44voto

John Leidegren Points 21951

Il y a une différence dans les performances.

En bref HS256 est environ un ordre de grandeur plus rapide que RS256 pour la vérification mais environ 2 ordres de grandeur plus rapide que RS256 pour la délivrance (signature).

 640,251  91,464.3 ops/s
  86,123  12,303.3 ops/s (RS256 verify)
   7,046   1,006.5 ops/s (RS256 sign)

Ne vous attachez pas aux chiffres réels, mais considérez-les les uns par rapport aux autres.

[Program.cs]

class Program
{
    static void Main(string[] args)
    {
        foreach (var duration in new[] { 1, 3, 5, 7 })
        {
            var t = TimeSpan.FromSeconds(duration);

            byte[] publicKey, privateKey;

            using (var rsa = new RSACryptoServiceProvider())
            {
                publicKey = rsa.ExportCspBlob(false);
                privateKey = rsa.ExportCspBlob(true);
            }

            byte[] key = new byte[64];

            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(key);
            }

            var s1 = new Stopwatch();
            var n1 = 0;

            using (var hs256 = new HMACSHA256(key))
            {
                while (s1.Elapsed < t)
                {
                    s1.Start();
                    var hash = hs256.ComputeHash(privateKey);
                    s1.Stop();
                    n1++;
                }
            }

            byte[] sign;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(privateKey);

                sign = rsa.SignData(privateKey, "SHA256");
            }

            var s2 = new Stopwatch();
            var n2 = 0;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(publicKey);

                while (s2.Elapsed < t)
                {
                    s2.Start();
                    var success = rsa.VerifyData(privateKey, "SHA256", sign);
                    s2.Stop();
                    n2++;
                }
            }

            var s3 = new Stopwatch();
            var n3 = 0;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(privateKey);

                while (s3.Elapsed < t)
                {
                    s3.Start();
                    rsa.SignData(privateKey, "SHA256");
                    s3.Stop();
                    n3++;
                }
            }

            Console.WriteLine($"{s1.Elapsed.TotalSeconds:0} {n1,7:N0} {n1 / s1.Elapsed.TotalSeconds,9:N1} ops/s");
            Console.WriteLine($"{s2.Elapsed.TotalSeconds:0} {n2,7:N0} {n2 / s2.Elapsed.TotalSeconds,9:N1} ops/s");
            Console.WriteLine($"{s3.Elapsed.TotalSeconds:0} {n3,7:N0} {n3 / s3.Elapsed.TotalSeconds,9:N1} ops/s");

            Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n2 / s2.Elapsed.TotalSeconds),9:N1}x slower (verify)");
            Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n3 / s3.Elapsed.TotalSeconds),9:N1}x slower (issue)");

            // RS256 is about 7.5x slower, but it can still do over 10K ops per sec.
        }
    }
}

0 votes

Ce sont des chiffres importants. Merci. J'ai tendance à penser que le cryptage est plus ou moins transparent par rapport au débit, mais votre recherche implique que l'utilisation du R256 pour signer les communications inter-machines ajoute 1 ms par saut.

3 votes

Gardez à l'esprit qu'ils ne sont pas égaux dans leur utilisation. Ils ont des caractéristiques différentes. RS256 est asymétrique et donc dans une communication de type client/serveur où vous ne partagez que la clé publique, c'est une meilleure option. HS256 nécessite le partage de la clé qui peut à la fois signer ET vérifier - ce qui n'est utile que si vous faites confiance aux deux parties ou si vous n'avez pas besoin que l'une des parties déchiffre quoi que ce soit.

9 votes

@RobEvans oui, il ne faut pas s'accrocher aux chiffres de performance ici. Choisissez la bonne solution à votre problème. Il s'agit juste d'une observation, pas d'une recommandation de privilégier HS256 par rapport à RS256 ; vous devez prendre cette décision en fonction de votre contexte.

4voto

Hiran Points 309

Réponse courte, spécifique à OAuth2,

  • HS256 le secret du client utilisateur pour générer la signature du jeton et le même secret est requis pour valider le jeton en back-end. Vous devez donc avoir une copie de ce secret dans votre serveur back-end pour vérifier la signature.
  • RS256 La signature (hash) sera créée à l'aide d'une clé privée et pourra être vérifiée à l'aide d'une clé publique. Ainsi, il n'est pas nécessaire de stocker la clé privée ou le secret du client dans le serveur back-end, mais le serveur back-end récupérera la clé publique à partir de l'url de configuration openid dans votre locataire ( https://[locataire]/.well-known/openid-configuration ) pour vérifier le jeton. Le paramètre KID dans l'access_toekn sera utilisé pour détecter la bonne clé (publique) de la configuration openid.

0 votes

Vous devez toujours stocker la clé privée pour générer de nouveaux jetons.

0 votes

La clé privée de @DollarAkshay est utilisée par le serveur d'authentification (c'est sa propre clé privée). Personne ne stockera la clé privée des autres

0 votes

Oui, c'est ce que je veux dire, le serveur qui génère les jetons doit toujours stocker la clé privée. Mais vous avez dit que vous n'avez pas besoin de stocker la clé privée sur le serveur backend, ce qui est faux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X