Este equipo de expertos despúes de varios días de trabajo y recopilar de datos, obtuvimos los datos necesarios, queremos que todo este artículo sea de utilidad en tu plan.
Solución:
Todo es cuestión de formatos y codificación.
En https://jwt.io obtienes este token basado en tus valores de entrada y secreto:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
Queremos demostrar que la firma:
3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
es correcto.
La firma es un hash HMAC-SHA256 codificado en Base64url. (como se describe en RFC7515)
Cuando usa el generador HMAC en línea para calcular un hash para
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
con el secreto
hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6
usted obtiene
de921a2a4b225fd66ff0983e8566eb0f6e1584bdfa84120568da40e1f571dbd3
como resultado, que es un valor HMAC-SHA256, pero no codificado en Base64url. Este hash es un hexadecimal string representación de un gran número.
Para compararlo con el valor de https://jwt.io, debe convertir el valor de su hexadecimal string representación de nuevo a un número y Base64url lo codifica.
El siguiente script lo está haciendo y también usa crypto-js para calcular su propio hash. Esta también puede ser una forma de verificar sin bibliotecas JWT.
var CryptoJS = require("crypto-js");
// the input values
var base64Header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
var base64Payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ";
var secret = "hONPMX3tHWIp9jwLDtoCUwFAtH0RwSK6";
// two hashes from different online tools
var signatureJWTIO = "3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M";
var onlineCaluclatedHS256 = "de921a2a4b225fd66ff0983e8566eb0f6e1584bdfa84120568da40e1f571dbd3";
// hash calculation with Crypto-JS.
// The two replace expressions convert Base64 to Base64url format by replacing
// '+' with '-', '/' with '_' and stripping the '=' padding
var base64Signature = CryptoJS.HmacSHA256(base64Header + "." + base64Payload , secret).toString(CryptoJS.enc.Base64).replace(/+/g,'-').replace(///g,'_').replace(/=+$/m,'');
// converting the online calculated value to Base64 representation
var base64hash = new Buffer.from(onlineCaluclatedHS256, 'hex').toString('base64').replace(///g,'_').replace(/+/g,'-').replace(/=+$/m,'')
// the results:
console.log("Signature from JWT.IO : " + signatureJWTIO);
console.log("NodeJS calculated hash : " + base64Signature);
console.log("online calulated hash (converted) : " + base64hash);
Los resultados son:
Signature from JWT.IO : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
NodeJS calculated hash : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
online calulated hash (converted) : 3pIaKksiX9Zv8Jg-hWbrD24VhL36hBIFaNpA4fVx29M
¡idéntico!
Conclusión:
Los valores calculados por las diferentes herramientas en línea son todos correctos pero no directamente comparables debido a los diferentes formatos y codificaciones. Un pequeño script como se muestra arriba podría ser una mejor solución.
Tuve el mismo problema hasta que me di cuenta de que estaba usando base64
codificación en lugar de base64url
. También hay algunos detalles menores en el medio. Aquí está el manual paso a paso que, con suerte, hará que todo el proceso sea mucho más claro.
Notas
Nota 1: Debe eliminar todos los espacios y nuevas líneas de sus cadenas JSON (encabezado y carga útil). Se realiza implícitamente en jwt.io cuando genera un token JWT.
Nota 2: Para convertir JSON string para base64url
string en cryptii.com cree la siguiente configuración:
First view: Text
Second view: Encode
Encoding: Base64
Variant: Standard 'base64url' (RFC 4648 §5)
Third view: Text
Nota 3: Para convertir el código HMAC HEX (firma) a base64url
string en cryptii.com cree la siguiente configuración:
First view: Bytes
Format: Hexadecimal
Group by: None
Second view: Encode
Encoding: Base64
Variant: Standard 'base64url' (RFC 4648 §5)
Third view: Text
Manual
Solo necesitará dos herramientas en línea:
- [Tool 1]: cryptii.com – para
base64url
codificación - [Tool 2]: codebeautify.org – para el cálculo de HMAC.
En cryptii.com puedes hacer ambas cosas base64url
codificación / decodificación y también cálculo HMAC, pero para HMAC debe proporcionar un HEX key que es diferente de la entrada en jwt.io, por lo que utilicé un servicio separado para el cálculo de HMAC.
Los datos de entrada
En este manual utilicé los siguientes datos:
-
Encabezamiento:
"alg":"HS256","typ":"JWT"
-
Carga útil:
"sub":"1234567890","name":"John Doe","iat":1516239022
-
Secreto (key):
The Earth is flat!
El secreto no es base64
codificado.
Paso 1: convertir el encabezado [Tool 1]
-
Encabezado (texto sin formato):
"alg":"HS256","typ":"JWT"
-
Encabezado (
base64url
codificado):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Paso 2: convertir la carga útil [Tool 1]
-
Carga útil (texto sin formato):
"sub":"1234567890","name":"John Doe","iat":1516239022
-
Carga útil (
base64url
codificado):eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Paso 3: Calcule el código HMAC (firma) [Tool 2]
Calcule HMAC usando SHA256
algoritmo.
-
Aporte string (
base64url
encabezado codificado y carga útil, concatenados con un punto):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
-
Código calculado (número HEX):
c8a9ae59f3d64564364a864d22490cc666c74c66a3822be04a9a9287a707b352
El código HMAC calculado es una representación HEX de la firma.
Nota: no debe estar codificado para base64url
como texto plano string sino como una secuencia de bytes.
Paso 4: Codifique el código HMAC calculado para base64url
[Tool 1]:
-
Firma (Bytes):
c8a9ae59f3d64564364a864d22490cc666c74c66a3822be04a9a9287a707b352
-
Firma (
base64url
codificado):yKmuWfPWRWQ2SoZNIkkMxmbHTGajgivgSpqSh6cHs1I
Resumen
Aquí están nuestros resultados (todos base64url
codificado):
-
Encabezamiento:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
-
Carga útil:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
-
Firma:
yKmuWfPWRWQ2SoZNIkkMxmbHTGajgivgSpqSh6cHs1I
Los resultados de jwt.io:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.yKmuWfPWRWQ2SoZNIkkMxmbHTGajgivgSpqSh6cHs1I
Como puede ver, las tres partes son idénticas.
Te mostramos reseñas y valoraciones
Si tienes alguna perplejidad y capacidad de medrar nuestro escrito eres capaz de dejar un comentario y con mucho gusto lo leeremos.