According to my understanding a JWT can be broken down into a Header, Payload and a Signature. The signature is created using Header Payload Secret. The secret is stored by the server and is never shared.
When a client sends a JWT to the server. The server can authorize it by accessing the Header , Payload received from JWT and combine it with the secret to create a Test Signature. Then the server can check if Test Signature = Signature received from the client JWT and make sure the data is not altered.
• Does this mean that the entire JWT authorization is dependent on the Secret and the whole authorization process is compromised if it is leaked?
CodePudding user response:
Secret is matter to verify JWT
This diagram is normal sequence to use JWT for accessing resource by API call.
I would like to demo with real code.
Using jsonwebtoken java-script library on node-js
1. JWT generate step.
function name: generate_token()
first function parameter: secret
second function parameter: user name (or payload)
const jwt = require("jsonwebtoken")
const jwtExpirySeconds = 600
const generate_token = (jwtKey, username) => {
const token = jwt.sign({ username }, jwtKey, {
algorithm: "HS256",
expiresIn: jwtExpirySeconds,
})
console.log("JWT token:", token, '\n')
const [header, payload, signature] = token.split(".")
console.log("1) header:", header)
console.log(JSON.parse(Buffer.from(header, "base64").toString("utf8")), '\n')
console.log("2) payload:", payload)
console.log(JSON.parse(Buffer.from(payload, "base64").toString("utf8")), '\n')
console.log("3) signature:", signature)
}
const my_args = process.argv.slice(2);
generate_token(my_args[0], my_args[1]);
generate token with secret and user name
$ node generate_token.js my-secret user1
JWT token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwiaWF0IjoxNjU5NDA3NzQ0LCJleHAiOjE2NTk0MDgzNDR9.MMIxotVJjMBLFOg0nusePz4L62n7VZ4Q-fW_u392qDQ
1) header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{ alg: 'HS256', typ: 'JWT' }
2) payload: eyJ1c2VybmFtZSI6InVzZXIxIiwiaWF0IjoxNjU5NDA3NzQ0LCJleHAiOjE2NTk0MDgzNDR9
{ username: 'user1', iat: 1659407744, exp: 1659408344 }
3) signature: MMIxotVJjMBLFOg0nusePz4L62n7VZ4Q-fW_u392qDQ
2. Verify JWT step.
function name: verify_token()
first function parameter: secret
second function parameter: JWT token
const jwt = require("jsonwebtoken")
const verify_token = (jwtKey, token) => {
try {
payload = jwt.verify(token, jwtKey)
console.log("JWT token verify:", payload, '\n')
} catch (e) {
if (e instanceof jwt.JsonWebTokenError) {
console.log("JWT token error: 401")
return
}
// otherwise, return a bad request error
console.log("JWT token error: 400")
}
}
const my_args = process.argv.slice(2);
verify_token(my_args[0], my_args[1]);
2.1 verify token with correct secret and JWT token
$ node verify_token.js my-secret eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwiaWF0IjoxNjU5NDA3NzQ0LCJleHAiOjE2NTk0MDgzNDR9.MMIxotVJjMBLFOg0nusePz4L62n7VZ4Q-fW_u392qDQ
JWT token verify: { username: 'user1', iat: 1659407744, exp: 1659408344 }
2.2 if verify token with wrong secret and same JWT token
$node verify_token.js wrong-secret eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwiaWF0IjoxNjU5NDA3NzQ0LCJleHAiOjE2NTk0MDgzNDR9.MMIxotVJjMBLFOg0nusePz4L62n7VZ4Q-fW_u392qDQ
JWT token error: 401