Maciej Treder
July 29, 2020
110

# WT* is JWT

So what the hell is JWT, Jose header, JWKS, and others?

This presentation covers:
- the cryptography basics (symmetric ciphers, asymmetric ciphers, signing, and verifying)
- JWS (JSON Web Signature)
- JWE (JSON Web Encryption)
- JWT (JSON Web Token)
- JWKS (JSON Web Key Set)
- JWT security
- JWT vulnerabilities

July 29, 2020

## Transcript

1. @maciejtreder

2. What the **** is JWT?!
hell

3. I like you

4. I like you
I like you
I don’t like you!

5. I like you
I like you
I don’t like you!

6. Symmetric cipher
a b c d e f g h i j k l m
1 2 3 4 5 6 7 8 9 10 11 12 13
n o p r s t u v w x y z _
14 15 16 17 18 19 20 21 22 23 24 25 26
I like you
9 26 12 9 11 5 26 24 15 20

7. What if…?

8. Asymmetric cipher
• Private key - used to decrypt the message
• Public key - used to encrypt the message
• Keys are generated using the one-way function
f(p,q) = p*q where p & q are primes
• Keys can be used interchangeably

9. RSA key
• Select p & q primes
• Calculate n = p*q
• Calculate φ = (p-1)*(q-1)
• Choose such e, relatively prime to φ
gcd(φ,e) == 1
• Compute such d, that
(ed-1) modφ=0
• Private key = (n,e)
• Public key = (n,d)
p=11 q=3
n = 11*3 = 33
φ = (11-1)*(3-1) = 20
e = 3
d=7
(ed-1) mod φ = 0
(3d-1) mod 20 = 0
3d-1 = 20n
d = (20n + 1)/3
d = (20*1+1)/3
d = 21/3
public key = (n, e) = (33, 3)
private key = (n, d) = (33, 7)

10. Asymmetric cipher
Mikes public key
Mikes private key
Kates public key
Kates private key

11. Asymmetric cipher
c = m^e mod n public key = (n, e) = (33, 3)
private key = (n, d) = (33, 7)
a b c d e f g h i j k l m
m 2 3 4 5 6 7 8 9 10 11 12 13 14
c 8 27 31 26 18 13 17 3 10 11 12 19 5
n o p r s t u v w x y z _
m 15 16 17 18 19 20 21 22 23 24 25 26 27
c 9 4 29 24 28 14 21 22 23 30 16 20 15
I like you
10 15 19 10 12 18 15 16 4 21
m’ = c^d mod n

12. What if…?
Mikes public key
Mikes private key
Kates public key
Kates private key

13. Breaking the RSA
• Compromising public key gives an attacker the modulus n
• Key sizes - 1024 to 4096 bit (from 2^1024 to 2^4096)
• p:
109337661836325758176115170347306682871557999846322234541387456711212734562876700082908433028755212749702453145932
22946129064538358581018615539828479146469
• q:
109106169673491102317237340786149226453370608821417489682098342251389760111799933942998101597369044685540217082898
24396553412180514827996444845438176099727
• 1024 bit modulus:
119294134840169509055527211331255649644606569661527638012067481954943056851150333806315957037715620297305000118628
770846689969112892212245457118060574995989517080042105263427376322274266393116193517839570773505632231596681121927
337473973220312512599061231322250945506260066557538238517575390621262940383913963

14. Signing
• Write the message
• Hash the message
• Encrypt hash with your private key
• Combine message with hash
• Encrypt message+hash with their public key
• I like you
• f1d049f7b893bf8601c66045b801d590
• xxx-yyy-zzz
• I like you.xxx-yyy-zzz
• aaa-bbb-ccc

15. Verifying
• Decrypt using your private key
• Get original message & encrypted hash
• Hash the original message
• Decrypt received hash using their public key
• Compare hashes
• aaa-bbb-ccc
• I like you.xxx-yyy-zzz
• f1d049f7b893bf8601c66045b801d590
• xxx-yyy-zzz ->
f1d049f7b893bf8601c66045b801d590

16. Signing

17. Signing
+ =
- =

18. Signing

19. Signing
• Create a message
• Hash the message
• Encrypt hash with private key
• Combine message and encrypted hash
• From tomorrow everyone in the kingdom must use his le
hand to open the door.
• F03CF2EF5AFCE429DB88051746F3864B
• Vf2Lx/jOUNLoXawCw4disZhrFfqcoNRGDvpG+SbxUX0=
• {
“message”: “From tomorrow everyone in the kingdom must use his
le hand to open door.”
“signature”: “Vf2Lx/jOUNLoXawCw4disZhrFfqcoNRGDvpG+SbxUX0=”
}

20. Verifying
• Get the message
• Hash the message
• Decrypt the signature
• Compare hash with decrypted signature
• {
“message”: “From tomorrow everyone in the kingdom must use his le
hand to open door.”
“signature”: “Vf2Lx/jOUNLoXawCw4disZhrFfqcoNRGDvpG+SbxUX0=”
}
• F03CF2EF5AFCE429DB88051746F3864B
• Vf2Lx/jOUNLoXawCw4disZhrFfqcoNRGDvpG+SbxUX0=
• F03CF2EF5AFCE429DB88051746F3864B

21. That’s what most people call JWT

22. JSON Web Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJIGFtIjoiSlNPTiBXZWIgVG9rZW4if
Q.NmTt6oAkllTqmLqR-QqKxIgIsIaZIRIcBjNyhPnGziU
{"alg":"HS256","typ":"JWT"}.{"I am":"JSON Web Token"}.NmTt6oAkllTqmLqR-
QqKxIgIsIaZIRIcBjNyhPnGziU

23. JSON Web Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJIGFtIjoiSlNPTiBXZWIgVG9rZW4if
Q.NmTt6oAkllTqmLqR-QqKxIgIsIaZIRIcBjNyhPnGziU
Javascript Object Signing and Encryption
information about token type, encryption algorithm
• Signature - encrypted header and body

24. So.. What the **** is JWT?
• JWT does not exist itself
• Signed JWT is called JWS (JSON Web Signature)
• Encrypted JWT is called JWE (JSON Web Encryption)
JWT
JWS
JWE

25. Registered claims
{
"alg":"HS256",
"typ":"JWT"
}
{
"iss": "authorization-service",
"sub": "myself",
"aud": "someone",
"iat": 1594655553034,
"nbf": 1594655553134,
"exp": 1594655553234,
"jti": 12345
}
Algorithm used for signing
Token type
Issuer
Subject (the user)
Audience (recipient)
Issued at (time at which token was issued)
Not before (time before which token is not valid)
Expires (time a er which token is not valid)
Unique identifier

26. Custom claims
{
“alg":"RS512",
"typ":"JWT"
}
{
"name": "Maciej",
"surname": "Treder",
"privileges": ["booking_reschedule"],
"exp": 1594655553234
}
• Public claims - defined at will by those
using JWTs. To avoid collisions should
be defend in the IANA JSON Web Token
Registry
• Private claims - custom claims create to
share information between parties that
agree on using them

27. Pre JWT authorization
POST /auth
userID

28. Pre JWT authorization
POST /auth
userID
POST /book
POST /changeGate
POST /cancelFlight

29. Pre JWT authorization
POST /auth
userID
POST /book
POST /changeGate
POST /cancelFlight
canChange?
canBook?
canCancel?

30. Pre JWT authorization
POST /auth
userID
POST /book
POST /changeGate
POST /cancelFlight

31. JWT authorization
POST /auth
{privs: [“booking”], exp: 12345}

32. JWT authorization
POST /auth
{privs: [“booking”], exp: 12345}
POST /book
POST /changeGate
POST /cancelFlight

33. JWT authorization
POST /auth
{privs: [“booking”], exp: 12345}
POST /book
POST /changeGate
POST /cancelFlight

34. JWT authorization
POST /auth
POST /changeGate
@PostMapping("/changeGate")
public ResponseEntity changeGate(
@RequestBody Gate gate
) {
DecodedToken decoded = decodeToken(token);
if(decoded.hasPrivilege("changeGate") && verifySignature(token)) {
changeGate(gate);
return this.flightDetails;
}
throw new AuthorizationFailureException();
}
{privs: [“booking”]}

35. JWT authorization
verify claim and signature

36. Delegate validation to 3rd parties
verify claim and signature

37. Delegate validation to 3rd parties

• JSON web token validation
https://learn.akamai.com/en-us/webhelp/api-gateway/api-gateway-user-guide/
GUID-682D1D3F-4CF2-46F2-B16B-5E0E1E991218.html
• Protecting JavaScript Microservices on Node.js with JSON Web
Tokens and Twilio Authy
https://www.twilio.com/blog/protecting-javascript-microservices-node-js-json-web-tokens-twilio-
authy

39. OAuth

40. OAuth
authenticate
request resource
validate token
token valid
return resource
authenticate
client

41. OAuth
authenticate
request resource
return resource
authenticate
client
validate
token

42. JWKS
• What if my key get compromised?
• What if want to rotate keys?
• What if I want to invalidate someones access?
• JSON Web Key Set
• A repository of keys (public, private, symmetric)

43. JWKS
{
"alg":"HS256",
"typ":"JWT",
"kid":"12",
"jku":"https://my-service.com/.well-known/jwks.json"
}
{
"privileges": ["booking_reschedule"]
}
NmTt6oAkllTqmLqR-QqKxIgIsIaZIRIc

44. JWKS
{
"keys": [
{
"kty": "RSA",
"kid": "1",
"alg": "RS256",
"use": "sig",
"e": "AQAB",
"n": "ujZ1fTy2k-
xc6Fa3Bfqe1T78Zx_oWBkDS1TNgw8Jbvbzfj5wgK5
_xSK5ikNlkOXvBjrsVOnCCJXTNiHZxMtIfARbz91O-5n
cuNah1H6WntWrLmaVfiIMaaKoNjDzScG1cIjPITarEV
jDb0GI0eH9BKpFz8LUbVlcy2m7IOKbmDt6yusHsj7z
OfjlV55dT1FU-
q5bfyLXQyCf7Uy2JJAVEutWLMp3Ld53q9mvW47Lh
hXKl5pKKbLARJgkccpQdN0bURiggvYjs2SHmZgh6d
Ceap1mki4LB2aX-Z4TB-
u8GbLq51HPZSpK71rR0QzZozluS5aLE49ciQ6-5u7K
HWBbrQ"
}
]
}
Key type
Key ID
Algorithm
Usage
Exponent
Modulus

45. JWKS
Standard attributes:
• kty - key type
• kid - key ID
• alg - algorithm [HMAC, RSA, …]
• use - usage
• e - exponent number
• m - modulus number
Chinese remainder algorithm:
• p, q - prime factors
• dp - d (mod p-1)
• dq - d (mod q-1)
• qi - q^-1 (mod p)
Certificate:
• x5c - x.509 certificate chain
• x5t - Thumbprint of the x.509 cert

46. JWKS

47. JWKS

48. JWKS
{
"alg":"HS256",
"typ":"JWT",
"kid":"12",
"jku":"https://my-service.com/.well-known/jwks.json"
}
{
"privileges": ["change_gate"]
}
NmTt6oAkllTqmLqR-QqKxIgIsIaZIRIc

49. Pitfalls & Vulnerabilities

50. Data Security
• JWS payload is encoded not encrypted
• Never store sensitive data (ie. credit card numbers) in JWS token
• If you want to store sensitive data choose JWE

51. Unsigned JWT
• JWT doesn’t need to be signed
• Do not rely only on the header when you’re validating the token
• “alg”: “none”

52. Error Responses
• Pay attention to what you are providing in
the error response
• https://github.com/jwt-dotnet/jwt/issues/
61

53. Weak Key
• HS256 (HMAC-SHA256)
• Token is signed applying the SHA256 twice
• When attacker obtains a signed token, he can “easily” retrieve the key (ie. by using the HashCat)
• According to documentation, use key which has at least same size as the hash output (256 bit for
HS256)

54. Decoding != Verifying
• Decoding is enough only for denying access (lack of required claim)
• Always verify signature if you want grant someone access
• Read library documentation, o en verifying process is available as a separate method

55. “Time” attack
• Applies when signature is verified byte-a er-byte
• Once bytes doesn’t match then access is denied
• Attacker may observe the response time and generate next bytes of the signature

56. jku
• Always verify the URL provided as a jku claim
{
"alg":"HS256",
"typ":"JWT",
"kid":"12",
"jku":"https://attacker.com/.well-known/jwks.json"
}
{
"privileges": ["change_gate"]
}

57. jku validation

58. Summary
• JWT is o en confused with JWS which is one of it’s implementations
• It’s a way of stateless data exchange
• It’s a good place too keep not-sensitive data, which value should be verified
• Always follow given algorithm best practices (i.e. pass-phrase/key size)
• JWE is a good choice if you want to keep data encrypted

59. Resources
• JWT.IO
https://jwt.io
• JSON web token validation
https://learn.akamai.com/en-us/webhelp/api-gateway/api-gateway-user-guide/
GUID-682D1D3F-4CF2-46F2-B16B-5E0E1E991218.html
• Verify JWT With JSON Web Key Set (JWKS) In API Gateway
https://blogs.akamai.com/2019/10/verify-jwt-with-json-web-key-set-jwks-in-api-gateway.html
• RFC 7519 - JSON Web Token
https://tools.ietf.org/html/rfc7519

60. Resources
• Building JavaScript Microservices with Node.js
https://www.twilio.com/blog/building-javascript-microservices-node-js
• Implementing Eureka and Zuul for Service Discovery and Dynamic Routing in JavaScript
Microservices Running on Node.js
https://www.twilio.com/blog/eureka-zuul-service-discovery-dynamic-routing-javascript-microservices-node-js
• Scaling Node.js JavaScript Microservices on Shared MongoDB Atlas Cloud Persistence
Layers
https://www.twilio.com/blog/scale-node-js-javascript-microservices-shared-mongodb-atlas
• Protecting JavaScript Microservices on Node.js with JSON Web Tokens and Twilio Authy
https://www.twilio.com/blog/protecting-javascript-microservices-node-js-json-web-tokens-twilio-authy

61. Feedback
https://bit.ly/2DbNOcM

62. @maciejtreder