jwtear 0.2.0 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,68 @@
1
+ module JWTear
2
+ module CLI
3
+ extend GLI::App
4
+ extend JWTear::Helpers::Extensions::Print
5
+ extend JWTear::Helpers::Utils
6
+ #
7
+ # JWS command
8
+ #
9
+ desc "Generate signature-based JWT (JWS) token."
10
+ command [:jws, :s] do |jws_cmd|
11
+ # Header
12
+ jws_cmd.desc %Q(JWT header (JSON format). eg. {"typ":"JWT","alg":"HS256"}. Run 'jwtear gen -l' for supported algorithms.)
13
+ jws_cmd.arg_name 'JSON'
14
+ jws_cmd.flag [:h, :header], required: true
15
+ # Payload
16
+ jws_cmd.desc 'JWT payload (JSON format). eg. {"login":"admin"}'
17
+ jws_cmd.arg_name 'JSON'
18
+ jws_cmd.flag [:p, :payload], required: true
19
+ # Password or public key file
20
+ jws_cmd.desc "Key as a password string or a file public key. eg. P@ssw0rd | eg. public_key.pem"
21
+ jws_cmd.arg_name 'PASSWORD|PUB_KEY_FILE'
22
+ jws_cmd.flag [:k, :key]
23
+ jws_cmd.action do |global, options, args|
24
+ gen = Generate.new
25
+ puts gen.jws_token(options[:header], options[:payload], read_key(options[:key]))
26
+ end
27
+ end
28
+
29
+ #
30
+ # JWE command
31
+ #
32
+ desc "Generate encryption-based JWT (JWE) token."
33
+ command [:jwe, :e] do |jwe_cmd|
34
+ jwe_cmd.desc %Q(JWT header (JSON format). eg. {"alg"=>"RSA-OAEP", "enc"=>"A192GCM"})
35
+ jwe_cmd.arg_name 'JSON'
36
+ jwe_cmd.flag [:h, :header]#, required: true
37
+ # Payload
38
+ jwe_cmd.desc 'JWT payload (JSON format). eg. {"login":"admin"}'
39
+ jwe_cmd.arg_name 'JSON'
40
+ jwe_cmd.flag [:p, :payload], required: true
41
+ # Password or public key file
42
+ jwe_cmd.desc "Key as a password string or a file public key. eg. P@ssw0rd | eg. public_key.pem"
43
+ jwe_cmd.arg_name 'PASSWORD|PUB_KEY_FILE'
44
+ jwe_cmd.flag [:k, :key]
45
+ jwe_cmd.action do |_, options, _|
46
+ gen = Generate.new
47
+ puts gen.jwe_token(options[:header], options[:payload], read_key(options[:key]))
48
+ end
49
+ end
50
+ end
51
+
52
+ class Generate
53
+ include JWTear::Helpers::Extensions::Print
54
+
55
+ def initialize
56
+ @token_ops = Token.new
57
+ end
58
+
59
+ def jws_token(header, payload, key=nil)
60
+ @token_ops.generate(:jws, header: header, payload:payload , key: key)
61
+ end
62
+
63
+ def jwe_token(header, payload, key=nil)
64
+ @token_ops.generate(:jwe, header: header, payload:payload , key: key)
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,111 @@
1
+ module JWTear
2
+ module CLI
3
+ extend GLI::App
4
+ extend JWTear::Helpers::Extensions::Print
5
+
6
+ desc "Parse JWT token (accepts JWS and JWE formats)."
7
+ arg_name "JWT_TOKEN", :required
8
+ command [:parse] do |c|
9
+ c.desc "JWT token to parse. (Accept JWS and JWE formats)"
10
+ c.arg_name 'JWT_TOKEN'
11
+ c.flag [:t, :token], required: true
12
+ c.example'jwtear parse -t eyJhb...pXUyJ.eyJsb...DgwIn.YjY4Z...DgzYThkOGJiZQ',
13
+ desc: 'parse token'
14
+ c.action do |_, options, _|
15
+ # if options[:token].nil?
16
+ # print_error "Missing option: -t/--t"
17
+ # exit!
18
+ # end
19
+ parse = Plugin::Parse.new
20
+ parse.token(options[:token])
21
+ end
22
+ end
23
+ end
24
+
25
+ module Plugin
26
+ class Parse
27
+ include JWTear::Helpers::Extensions::Print
28
+
29
+ def initialize
30
+ @token_ops = Token.new
31
+ end
32
+
33
+ def token(token)
34
+ @token = @token_ops.parse(token)
35
+ token_type = @token.class.to_s.split('::').last
36
+ puts
37
+ print_h1 token_type
38
+ case token_type
39
+ when "JWS" then print_jws
40
+ when "JWE" then print_jwe
41
+ else
42
+ print_error "Unknown type."
43
+ end
44
+ end
45
+
46
+ def print_jws
47
+ puts @token.to_json_presentation
48
+ puts
49
+ print_jwt_header(@token.header)
50
+ print_jws_payload(@token.payload)
51
+ print_jws_sig(@token.signature)
52
+ end
53
+
54
+ def print_jwe
55
+ puts @token.to_json_presentation
56
+ puts
57
+ print_jwt_header(@token.header)
58
+ print_jwe_cek(@token)
59
+ print_jwe_iv(@token)
60
+ print_jwe_cipher_text(@token)
61
+ print_jwe_authentication_tag(@token)
62
+ end
63
+
64
+ def print_jwe_cek(token)
65
+ print_h2 "Encrypted key (CEK)"
66
+ if token.is_encrypted?(token.encrypted_key)
67
+ puts Base64.urlsafe_encode64(token.encrypted_key)
68
+ else
69
+ puts token.encrypted_key
70
+ JSON.parse(token.encrypted_key).each do |k, v|
71
+ puts " - " + "#{k}: ".cyan.bold + "#{v}"
72
+ end
73
+ end
74
+ end
75
+
76
+ def print_jwt_header(header)
77
+ print_h2 "Header"
78
+ header.each do |k, v|
79
+ print_h3 "#{k}" , "#{v}"
80
+ end
81
+ end
82
+
83
+ def print_jws_payload(payload)
84
+ print_h2 "Payload"
85
+ payload.each do |k, v|
86
+ print_h3 "#{k}" , "#{v}"
87
+ end
88
+ end
89
+
90
+ def print_jws_sig(signature)
91
+ print_h2 "Signature - B64 encoded"
92
+ puts Base64.urlsafe_encode64(@token.signature, padding: false)
93
+ end
94
+
95
+ def print_jwe_iv(token)
96
+ print_h2 "Initial vector (IV)"
97
+ puts Base64.urlsafe_encode64(token.iv)
98
+ end
99
+
100
+ def print_jwe_cipher_text(token)
101
+ print_h2 "Cipher text"
102
+ puts Base64.urlsafe_encode64(token.cipher_text)
103
+ end
104
+
105
+ def print_jwe_authentication_tag(token)
106
+ print_h2 "authentication tag"
107
+ puts Base64.urlsafe_encode64(token.authentication_tag)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,32 @@
1
+ module JWTear
2
+ module CLI
3
+ extend GLI::App
4
+ extend JWTear::Helpers::Extensions::Print
5
+ extend JWTear::Helpers::Utils
6
+
7
+ # Uncomment the following line to enable the template
8
+
9
+ # desc "Plugin short description"
10
+ # long_desc "Plugin long description"
11
+ # command [:template, :pt] do |c|
12
+ # c.action do |g,o,a|
13
+ # print_h1 "Plugin template"
14
+ # print_good "Hi, I'm a template."
15
+ # template = TemplatePlugin.new
16
+ # end
17
+ # end
18
+
19
+ end
20
+
21
+ module Plugin
22
+ class TemplatePlugin
23
+ include JWTear::Helpers::Extensions::Print
24
+ include JWTear::Helpers::Utils
25
+
26
+ def initialize
27
+ check_dependencies
28
+ end
29
+ # ..code...
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ module JWTear
2
+ module CLI
3
+ extend GLI::App
4
+ extend JWTear::Helpers::Extensions::Print
5
+ extend JWTear::Helpers::Utils
6
+
7
+ desc "A JWT wiki for hackers."
8
+ long_desc "Wiki wiki Wiki wiki Wiki wiki Wiki wiki Wiki wiki Wiki wiki"
9
+ command [:wiki, :w] do |c|
10
+
11
+ c.desc "Show the wiki page on terminal"
12
+ c.switch [:r, :read], negatable: false
13
+
14
+ c.desc "Update wiki from the official repository"
15
+ c.switch [:u, :update], negatable: false
16
+
17
+ c.action do |_, options, _|
18
+ options[:update] ? Plugin::Wiki.update : Plugin::Wiki.read
19
+ end
20
+ end
21
+ end
22
+
23
+ module Plugin
24
+ class Wiki
25
+ extend JWTear::Helpers::Extensions::Print
26
+
27
+ def self.read
28
+ parsed = TTY::Markdown.parse_file('plugins/wiki/README.md', width: 80)
29
+ pager = TTY::Pager.new
30
+ pager.page(parsed)
31
+ end
32
+
33
+ def self.update
34
+ require 'open-uri'
35
+ print_status 'Updating wiki'
36
+ current_wiki = File.expand_path(File.join(__dir__ , 'wiki', 'README.md'))
37
+ updated_wiki = open('https://raw.githubusercontent.com/KINGSABRI/jwtear/master/plugins/wiki/README.md').read
38
+ if File.exists?(current_wiki) && File.writable?(current_wiki)
39
+ File.write(current_wiki, updated_wiki)
40
+ else
41
+ print_error "File not accessible #{current_wiki}"
42
+ end
43
+ print_good 'Update completed.'
44
+ rescue OpenURI::HTTPError => e
45
+ print_bad "URL not found (404)."
46
+ exit!
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,212 @@
1
+ # JWTear Wiki
2
+
3
+ ## JWT
4
+ JSON Web Token (JWT) defines a container to transport data between interested parties. It became an IETF standard in May 2015 with the RFC 7519. There are multiple applications of JWT. The OpenID Connect is one of them. In OpenID Connect the id_token is represented as a JWT. Both in securing APIs and Microservices, the JWT is used as a way to propagate and verify end-user identity.
5
+
6
+ A JWT can be used to:
7
+ - Propagate one’s identity between interested parties.
8
+ - Propagate user entitlements between interested parties.
9
+ - Transfer data securely between interested parties over a unsecured channel.
10
+ - Assert one’s identity, given that the recipient of the JWT trusts the asserting party.
11
+
12
+ Following is a sample JWT, which is returned back from the Google OpenID Connect provider. Here the Google, which is the identity provider, asserts the identity of an end-user and passes the JWT to a service provider (a web or native mobile application).
13
+
14
+ ```
15
+ eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc4YjRjZjIzNjU2ZGMzOTUzNjRmMWI2YzAyOTA3NjkxZjJjZGZmZTEifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTEwNTAyMjUxMTU4OTIwMTQ3NzMyIiwiYXpwIjoiODI1MjQ5ODM1NjU5LXRlOHFnbDcwMWtnb25ub21ucDRzcXY3ZXJodTEyMTFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJwcmFiYXRoQHdzbzIuY29tIiwiYXRfaGFzaCI6InpmODZ2TnVsc0xCOGdGYXFSd2R6WWciLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXVkIjoiODI1MjQ5ODM1NjU5LXRlOHFnbDcwMWtnb25ub21ucDRzcXY3ZXJodTEyMTFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiaGQiOiJ3c28yLmNvbSIsImlhdCI6MTQwMTkwODI3MSwiZXhwIjoxNDAxOTEyMTcxfQ.TVKv-pdyvk2gW8sGsCbsnkqsrS0T-H00xnY6ETkIfgIxfotvFn5IwKm3xyBMpy0FFe0Rb5Ht8AEJV6PdWyxz8rMgX2HROWqSo_RfEfUpBb4iOsq4W28KftW5H0IA44VmNZ6zU4YTqPSt4TPhyFC9fP2D_Hg7JQozpQRUfbWTJI
16
+ ```
17
+ This looks gibberish till you break it by periods (.) and base64url-decode each part. There are two periods in it, which break the whole string into three parts. Once you base64url-decode the fist part, it appears like below:
18
+
19
+ ```json
20
+ {"alg":"RS256","kid":"78b4cf23656dc395364f1b6c02907691f2cdffe1"}
21
+ ```
22
+
23
+ ## JOSE Header
24
+ This first part(once parted by the periods) of the JWT is known as the JOSE header . JOSE stands for Javascript Object Signing and Encryption — and it’s the name of the IETF working group, which works on standardizing the representation of integrity-protected data using JSON data structures. The above JOSE header indicates that it’s a signed message. Google asserts the identity of the end-user by signing the JWT, which carries data related to the user’s identity.
25
+
26
+ > A signed JWT is known as a JWS (JSON Web Signature). In fact a JWT does not exist itself — either it has to be a JWS or a JWE (JSON Web Encryption). Its like an abstract class — the JWS and JWE are the concrete implementations.
27
+
28
+ ```
29
+ JWT
30
+ |
31
+ .----` `---.
32
+ | |
33
+ JWS JWE
34
+ ```
35
+
36
+ Going back to the JOSE header returned back from Google, both the **alg** and **kid** elements there, are not defined in the JWT specification, but in the JSON Web Signature (JWS) specification. The JWT specification only defines two elements (typ and cty) in the JOSE header and both the JWS and JWE specifications extend it to add more appropriate elements.
37
+
38
+ **typ (type):**
39
+ The *typ* element is used to define the media type of the complete JWT. A media type is an identifier, which defines the format of the content, transmitted on the Internet. There are two types of components that process a JWT: JWT implementations and JWT applications. Nimbus is a JWT implementation in Java. The Nimbus library knows how to build and parse a JWT. A JWT application can be anything, which uses JWTs internally. A JWT application uses a JWT implementation to build or parse a JWT. In this case, the typ element is just another element for the JWT implementation. It will not try to interpret the value of it, but the JWT application would. The typ element helps JWT applications to differentiate the content of the JWT when the values that are not JWTs could also be present in an application data structure along with a JWT object. This is an optional element and if present for a JWT, it is recommended to use JWT as the media type.
40
+
41
+
42
+ **cty (content type):**
43
+ The *cty* element is used to define the structural information about the JWT. It is only recommended to use this element in the case of a nested JWT.
44
+
45
+ The JWS specification is not bound to any specific algorithm. All applicable algorithms for signing are defined under the JSON Web Algorithms (JWA) specification, which is the RFC 7518. The section 3.1 of RFC 7518 defines all possible **alg** element values for a JWS token. The value of the kid element provides an indication or a hint about the key, which is used to sign the message. Looking at the kid, the recipient of the message should know where and how to lookup for the key and find it.
46
+
47
+ > In a JWT, the members of the JSON object represented by the JOSE header describe the cryptographic operations applied to the JWT and optionally, additional properties of the JWT. Depending upon whether the JWT is a JWS or JWE, the corresponding rules for the JOSE header values apply. Both under the JWS and JWE, the JOSE header is a must — or in other words there exists no JWT without a JOSE header.
48
+
49
+ ### Claim Set
50
+ Focus back on the sample JWT returned back from Google. More precisely now we know its a JWS. Following shows the base64url-decoded claim set returned back from Google. The second part of the JWT (when parted by the period (.)) is known as the JWT claim set. White-spaces can be explicitly retained while building the JWT claim set — no canonicalization is required before base64url-encoding or decoding. Canonicalization is the process of converting different forms of a message into a single standard form. This is used mostly before signing XML messages.
51
+ ```json
52
+ {
53
+ "iss":"accounts.google.com",
54
+ "sub":"115.654832477893315823",
55
+ "azp":"26655622859-np4sqv7erh12311s.apps.googleusercontent.com",
56
+ "email":"prabath@wso2.com",
57
+ "at_hash":"zf86vNulsLB*gFaqRwdzYg",
58
+ "email_verified":true,
59
+ "aud":"26655622859-np4sqv7erh12311s.apps.googleusercontent.com",
60
+ "hd":"wso2.com",
61
+ "iat":1401908271,
62
+ "exp":1401908271
63
+ }
64
+ ```
65
+
66
+ The JWT claim set represents a JSON object whose members are the claims asserted by the JWT issuer. Each claim name within a JWT must be unique. If there are duplicate claim names, then the JWT parser could either return a parsing error or just return back the claims set with the very last duplicate claim. JWT specification does not explicitly define what claims are mandatory and what are optional. It’s up to the each application of JWT to define mandatory and optional claims. For example, the OpenID Connect specification defines the mandatory and optional claims. According to the OpenID Connect core specification, iss, sub, aud, exp and iat are treated as mandatory elements, while auth_time, nonce, acr, amr and azp are optional elements. In addition to the mandatory and optional claims, which are defined in the specification, the identity provider can include additional elements into the JWT claim set.
67
+
68
+ ### Signature
69
+
70
+ Once again, focus back on the sample JWT returned back from Google. The third part of the JWT (when parted by the period (.)), is the signature, which is also base64url-encoded. The cryptographic elements related to the signature are defined in the JOSE header. In this particular example, Google uses RSASSA-PKCS1-V1_5 with the SHA-256 hashing algorithm, which is expressed by the value of the alg element in the JOSE header: RS256.
71
+
72
+
73
+ ### Serialization
74
+
75
+ A signed or an encrypted message can be serialized in two ways by following the JWS or JWE specification: the JWS/JWE compact serialization and the JWS/JWE JSON serialization. The Google OpenID Connect response discussed before uses the JWS compact serialization. In fact, the OpenID Connect specification mandates to use JWS compact serialization and JWE compact serialization whenever necessary.
76
+
77
+ Now we can further refine our definition of the JWT. So far we know that both the JWS and JWE tokens are instances of the JWT. But that is not 100% precise. We call a JWS or JWE, a JWT only if it follows the compact serialization. Any JWT must follow compact serialization. In other words a JWS or JWE token, which follows JSON serialization cannot be called as a JWT.
78
+
79
+ ## JWS Compact Serialization
80
+
81
+ JWS compact serialization represents a signed JWT as a compact URL-safe string. This compact string has three main elements separated by periods (.): the JOSE header, the JWS payload and the JWS signature. If you use compact serialization against a JSON payload (or any payload — even XML), then you can have only a single signature, which is computed over the complete JOSE header and JWS payload.
82
+
83
+ ```
84
+ BASE64URL(UTF8(JWS Header)) + '.' +
85
+ BASE64URL(JWS Payload) + '.' +
86
+ BASE64URL(JWS Signature)
87
+ ```
88
+
89
+ ### JWS Compact Serialization — Signing Process
90
+
91
+ Following lists out the signing process of a JWS under the compact serialization.
92
+
93
+ * Build a JSON object including all the header elements, which express the cryptographic properties of the JWS token — this is known as the JOSE header. As discussed before, the token issuer should advertise in the JOSE header, the public key corresponding to the key used to sign the message. This can be expressed via any of these header elements: jku, jwk, kid, x5u, x5c, x5t and x5t#s256.
94
+ * Compute the base64url-encoded value against the UTF-8 encoded JOSE header from the 1st step, to produce the 1st element of the JWS token.
95
+ * Construct the payload or the content to be signed — this is known as the JWS payload. The payload is not necessarily JSON — it can be any content. Yes, you read it correctly, the payload of a JWS necessarily need not to be JSON - if you’d like it can be XML too.
96
+ * Compute the base64url-encoded value of the JWS payload from the previous step to produce the 2nd element of the JWS token.
97
+ * Build the message to compute the digital signature or the Mac. The message is constructed as ASCII(BASE64URL-ENCODE(UTF8(JOSE Header)) ‘.’ BASE64URL-ENCODE(JWS Payload)).
98
+ * Compute the signature over the message constructed in the previous step, following the signature algorithm defined by the JOSE header element alg. The message is signed using the private key corresponding to the public key advertised in the JOSE header.
99
+ * Compute the base64url encoded value of the JWS signature produced in the previous step, which is the 3rd element of the serialized JWS token.
100
+ * Now we have all the elements to build the JWS token in the following manner. The line breaks are introduced only for clarity.
101
+
102
+
103
+
104
+ ## JWE Compact Serialization
105
+
106
+ With the JWE compact serialization, a JWE token is built with five key components, each separated by a period (.): JOSE header, JWE Encrypted Key, JWE initialization vector, JWE Additional Authentication Data (AAD), JWE Ciphertext and JWE Authentication Tag.
107
+
108
+ ```
109
+ BASE64URL(UTF8(JWE Protected Header)) + '.' +
110
+ BASE64URL(JWE Encrypted Key) + '.' +
111
+ BASE64URL(JWE Initialization Vector) + '.' +
112
+ BASE64URL(JWE Ciphertext) + '.' +
113
+ BASE64URL(JWE Authentication Tag)
114
+ ```
115
+
116
+ The JOSE header is the very first element of the JWE token produced under compact serialization. The structure of the JOSE header is the same, as we discussed under JWS other than couple of exceptions. The JWE specification introduces two new elements (enc and zip), which are included in the JOSE header of the JWE token, in addition to what’s defined by the JSON Web Signature (JWS) specification.
117
+
118
+ To understand JWE Encrypted Key section of the JWE, we first need to understand how a JSON payload gets encrypted. The enc element of the JOSE header defines the content encryption algorithm and it should be a symmetric Authenticated Encryption with Associated Data (AEAD) algorithm. The alg element of the JOSE header defines the encryption algorithm to encrypt the Content Encryption Key (CEK). This algorithm can also be defined as the key wrapping algorithm, as it wraps the CEK.
119
+
120
+ *Authenticated Encryption with Associated Data (AEAD) is a block cipher mode of operation which simultaneously provides confidentiality, integrity, and authenticity assurances on the data; decryption is combined in single step with integrity verification.*
121
+
122
+ Let’s look at the following JOSE header. For content encryption, it uses A256GCM algorithm; and for key wrapping, RSA-OAEP:
123
+
124
+ ```json
125
+ {"alg":"RSA-OAEP","enc":"A256GCM"}
126
+ ```
127
+
128
+ A256GCM is defined in the JWA specification. It uses the Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM) algorithm with a 256-bit long key, and it’s a symmetric key algorithm used for AEAD. Symmetric keys are mostly used for content encryption and it is much faster than asymmetric-key encryption. At the same time, asymmetric-key encryption can’t be used to encrypt large messages.
129
+
130
+ RSA-OAEP is too defined in the JWA specification. During the encryption process, the token issuer generates a random key, which is 256 bits in size and encrypts the message using that key following the AES GCM algorithm. Next, the key used to encrypt the message is encrypted using RSA-OAEP, which is an asymmetric encryption scheme. The RSA-OAEP encryption scheme uses RSA algorithm with the Optimal Asymmetric Encryption Padding (OAEP) method. Finally the encrypted symmetric key is placed in the JWE Encrypted Header section of the JWE.
131
+
132
+ Some encryption algorithms, which are used for content encryption require an initialization vector, during the encryption process. Initialization vector is a randomly generated number, which is used along with a secret key to encrypt data. This will add randomness to the encrypted data, which will prevent repetition even the same data gets encrypted using the same secret key again and again. To decrypt the message at the token recipient end, it has to know the initialization vector, hence it is included in the JWE token, under the JWE Initialization Vector element. If the content encryption algorithm does not require an initialization vector, then the value of this element should be kept empty.
133
+
134
+ The fourth element of the JWE token is the base64url-encoded value of the JWE ciphertext. The JWE ciphertext is computed by encrypting the plaintext JSON payload using the Content Encryption Key (CEK), the JWE initialization vector and the Additional Authentication Data (AAD) value, with the encryption algorithm defined by the header element enc. The algorithm defined by the enc header element should be a symmetric Authenticated Encryption with Associated Data (AEAD) algorithm. The AEAD algorithm, which is used to encrypt the plaintext payload, also allows specifying Additional Authenticated Data (AAD).
135
+
136
+ The base64url-encoded value of the JWE Authenticated Tag is the final element of the JWE token. As discussed before the value of the authentication tag is produced during the AEAD encryption process, along with the ciphertext. The authentication tag ensures the integrity of the ciphertext and the Additional Authenticated Data (AAD).
137
+
138
+ ### JWE Compact Serialization — Signing Process
139
+
140
+ Following lists out the encryption process of a JWE under the compact serialization.
141
+
142
+ * Figure out the key management mode by the algorithm used to determine the Content Encryption Key (CEK) value. This algorithm is defined by the alg element in the JOSE header. There is only one alg element per JWE token.
143
+ * Compute the CEK and calculate the JWE Encrypted Key based on the key management mode, picked in the previous. The CEK is later used to encrypt the JSON payload. There is only one JWE Encrypted Key element in the JWE token.
144
+ * Compute the base64url-encoded value of the JWE Encrypted Key, which is produced in the previous step. This is the 2nd element of the JWE token.
145
+ * Generate a random value for the JWE Initialization Vector. Irrespective of the serialization technique, the JWE token will carry the value of the base64url-encoded value of the JWE Initialization Vector. This is the 3rd element of the JWT token.
146
+ * If token compression is needed, the JSON payload in plaintext must be compressed following the compression algorithm defined under the zip header element.
147
+ * Construct the JSON representation of the JOSE header and find the base64url-encoded value of the JOSE header with UTF8 encoding. This is the 1st element of the JWE token.
148
+ * To encrypt the JSON payload, we need the CEK (which we already have), the JWE Initialization Vector (which we already have), and the Additional Authenticated Data (AAD). Compute ASCII value of the encoded JOSE header from the previous step and use it as the AAD.
149
+ * Encrypt the compressed JSON payload (from the previous step) using the CEK, the JWE Initialization Vector and the Additional Authenticated Data (AAD), following the content encryption algorithm defined by the header enc header element.
150
+ * The algorithm defined by the enc header element is a AEAD algorithm and after the encryption process, it produce the ciphertext and the Authentication Tag.
151
+ * Compute the base64url-encoded value of the ciphertext, which is produced by the step one before the previous. This is the 4th element of the JWE token.
152
+ * Compute the base64url-encoded value of the Authentication Tag, which is produced by the step one before the previous. This is the 5th element of the JWE token.
153
+ * Now we have all the elements to build the JWE token in the following manner. The line breaks are introduced only for clarity.
154
+
155
+ ### JWE Initialization Vector
156
+
157
+ This carries the same meaning as explained under JWE compact serialization, previously. The iv element in the JWE token represents the value of the initialization vector used for encryption.
158
+
159
+ ### JWE Ciphertext
160
+
161
+ This carries the same meaning as explained under JWE compact serialization, previously. The ciphertext element in the JWE token carries the base64url-encoded value of the JWE ciphertext
162
+
163
+ ### JWE Authentication Tag
164
+
165
+ This carries the same meaning as explained under JWE compact serialization, previously. The tag element in the JWE token carries the base64url-encoded value of the JWE authenticated tag, which is an outcome of the encryption process using an AEAD algorithm.
166
+
167
+ ---
168
+
169
+
170
+ ## Attacks
171
+
172
+ ### JWS
173
+
174
+ * Change the algorithm from HS256 to none.
175
+ * Change the algorithm from RS256 to HS256, and use the public key as the secret key for the HMAC.
176
+ * Crack\Bruteforce the HMAC signature key. Then create a new token with the discovered password
177
+ * Change the user to admin and keep the header and signature as is.
178
+
179
+
180
+ ### JWE
181
+
182
+ * Decode the token, change the payload, then use the target's public key (e.g. public.key, pub.key) to encrypt them.
183
+
184
+
185
+ ## Vulnerable Applications
186
+
187
+ * [Damn Vulnerable Web Services - DVWS](https://github.com/snoopysecurity/dvws)
188
+ * [Pentesterlab(Free)| JSON Web Token I](https://pentesterlab.com/exercises/jwt/)
189
+ * [Pentesterlab(PRO) | JSON Web Token II](https://pentesterlab.com/exercises/jwt_ii/)
190
+ * [Pentesterlab(PRO) | JWT III](https://pentesterlab.com/exercises/jwt_iii/)
191
+ * [Pentesterlab(PRO) | JWT IV](https://pentesterlab.com/exercises/jwt_iv)
192
+ * [Pentesterlab(PRO) | JWT V](https://pentesterlab.com/exercises/jwt_v)
193
+ * [Pentesterlab(PRO) | JWT VI](https://pentesterlab.com/exercises/jwt_vi)
194
+ * [Pentesterlab(PRO) | JWT VII](https://pentesterlab.com/exercises/jwt_vii)
195
+ * [Pentesterlab(PRO) | JWT VIII](https://pentesterlab.com/exercises/jwt_viii)
196
+ * [Pentesterlab(PRO) | JWT X](https://pentesterlab.com/exercises/jwt_x/)
197
+ * [Pentesterlab(PRO) | JWT XI](https://pentesterlab.com/exercises/jwt_xi)
198
+ * [Pentesterlab(PRO) | JWT XII](https://pentesterlab.com/exercises/jwt_xii)
199
+ * [Pentesterlab(PRO) | JSON Web Encryption](https://pentesterlab.com/exercises/jwe)
200
+ * [Vulnerable JWT implementations](https://github.com/Sjord/jwtdemo)
201
+
202
+ ## Resources
203
+ * [JWT, JWS and JWE for Not So Dummies! (Part I)](https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3)
204
+ * [OpenID - JWT, JWS, JWE, JWK, and JWA Implementations](https://openid.net/developers/jwt/)
205
+ * [List of JWT libraries](https://jwt.io/#libraries-io)
206
+ * [Attacking JWT authentication](https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/)
207
+ * [JWT: Signature-vs-MAC attacks](https://snikt.net/blog/2019/05/16/jwt-signature-vs-mac-attacks/)
208
+ * [JWT Attack Walk-Through](https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/)
209
+ * [Hack the JWT Token](https://habr.com/en/post/450054/)
210
+ * [Damn Vulnerable Service](https://github.com/snoopysecurity/dvws)
211
+ * [CSRF JWT redirect leak](https://gist.github.com/stefanocoding/8cdc8acf5253725992432dedb1c9c781)
212
+ * [Critical vulnerabilities in JSON Web Token libraries](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/)