web-dev-qa-db-fra.com

Dois-je être en mesure de voir les modèles dans un JWT encodé HS256?

Je jouais avec https://jwt.io/ en utilisant cet en-tête

{
  "alg": "HS256",
  "typ": "JWT"
}

quand j'ai réalisé que remplacer le nom de la charge utile par quelque chose de répétitif comme AAAAAAAAAAAAAAAAAAAA produirait un jeton comme celui-ci:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY

Vous pouvez voir que la sous-chaîne BQUF semble être répétée. Plus As j'ai ajouté au nom, plus BQUFs apparaît.

Autant que je sache, la présence de ce type de motifs facilite considérablement la découverte du contenu encodé. Qu'est-ce que je rate?

32
jmacedo

Il y a un peu de confusion de terminologie ici.

JWT définit le format de base des revendications et certaines revendications standard. Il spécifie que l'ensemble de revendications JWT doit être la charge utile d'un JWS ou d'une structure JWE.

JWS définit une structure pour une charge utile avec une signature. Bien que la charge utile soit presque toujours JWT dans la pratique, ce n'est pas une exigence de la spécification. La forme la plus courante est la sérialisation compacte JWS, qui est le Base64'd Header.Payload.Signature que vous connaissez. Notez qu'il n'y a aucun chiffrement impliqué, seulement la signature. Cela peut1 garantir que le jeton a été créé par une partie de confiance et non modifié (authenticité), mais ne masquera pas son contenu.

JWE est l'homologue chiffré de JWS. Tout comme JWS, il contient le plus souvent une charge utile JWT (comme son texte en clair) mais ce n'est pas une exigence. La sérialisation compacte JWE est quelque peu différente de l'équivalent JWS: Header.Key.IV.Ciphertext.AuthenticationTag. Ceci devrait1 avoir les mêmes garanties de sécurité (authenticité)2 en tant que JWS, avec en plus de cacher le message à toute personne sans clé (confidentialité).


Ce que vous avez là est spécifiquement un JWS, qui est signé mais non chiffré (comme on le voit dans le HS256 algorithme, qui signifie " HMAC en utilisant SHA-256 "). Si vous avez besoin d'un chiffrement, vous devez plutôt créer un JWE avec l'un des algorithmes de chiffrement définis par JWA .


Lectures complémentaires:


1 Comme toujours, toute "garantie" dépend de la configuration correcte de tout. Et que vous n'êtes pas par exemple en utilisant une configuration de débogage qui laisse tout non chiffré/non signé.

2 En supposant un cryptage authentifié.

27
Bob

tl/dr : Votre version sélectionnée du JWT ne crypte rien, elle le code simplement pour un transport facile. Les données de la charge utile ne sont pas censées être un secret.

Vous avez un JWS (JWT avec signature). Ce que vous regardez, c'est simplement la charge utile des données encodées en base64. Un JWS contient parties :

  1. L'en-tête encodé en base64
  2. Les données encodées en base64
  3. Une signature cryptographique

Base64 est simplement un format d'encodage - pas n'importe quel type de cryptage, et n'est pas destiné à masquer les données. Au lieu de cela, il s'assure simplement qu'il est composé uniquement de caractères standard ASCII qui survivent facilement au transfert entre différents systèmes. Par conséquent, si vous deviez tout prendre entre les deux périodes et le parcourir un décodeur base64, vous verriez vos données de charge utile d'origine sans problème.

La clé est donc simple: un JWS n'est pas destiné à cacher les données. Il est simplement destiné (via la signature) à garantir l'intégrité des données, c'est-à-dire que si quelqu'un modifie la charge utile des données, vous le saurez car votre signature ne correspondra plus.

Vous pouvez également utiliser un JWE (JWT avec cryptage) pour masquer vos données. Voir Bob's excellente réponse pour une comparaison plus détaillée entre JWT, JWS et JWE, qui sont tous étroitement liés.

50
Conor Mancone

Ce qui vous manque, c'est que votre token est signé ( ou, plus précisément, authentifié avec une clé symétrique ) mais pas crypté.

Si vous prenez le jeton dans votre question ci-dessus, divisez-le en trois morceaux aux périodes (.) et introduisez chaque morceau dans un décodeur base64 , vous obtiendrez les sorties décodées suivantes:

{"alg":"HS256","typ":"JWT"}
{"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022}

et une séquence de 32 octets pour la plupart non ASCII qui est la balise d'authentification HMAC 256 bits pour le reste du jeton. Comme vous pouvez le voir, toutes les données sont facilement lisibles par n'importe qui. La balise d'authentification empêche uniquement quiconque ne connaît pas la clé HMAC secrète de modifier le jeton ou de créer des jetons falsifiés à partir de zéro.

14
Ilmari Karonen