jwtear 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64f91b4e924b43dd19b0071db21dc93cdbf5b37a
4
- data.tar.gz: 241b7dd36ea2fcee9bbf1644e08ae5eaf7ac1b03
3
+ metadata.gz: bd40b5099b880a09ed4277d0964f85d0255a1be9
4
+ data.tar.gz: 9b016a13f78d711c0b1e4e61de499ed5bdfa30fb
5
5
  SHA512:
6
- metadata.gz: 6592677502c4af5a925159651cbb47aa8e9798c9c38dc6fc580823ba186f125b7628774348620cf2f7442f5fea8e871578c8d79465daa3ab3ff03f1c85d9c055
7
- data.tar.gz: 0f0f310463e42be3eda35d75f9d70fbac6c6eda2fd93fa735564aad6d04809793f764079669c1a10abfde563063613c4d8e5fa1eadede5d81ea2a73a4c4989b9
6
+ metadata.gz: 5d2d82eeabaa80693048981de0f3e3c7ea5688ad3d4b833f9b0893050e04c442adba291a696ac143bfc7f5521b778624e4ed057abba887bbd040a710e2feef35
7
+ data.tar.gz: 4506e71a5e670fd92c23584e9aa2d2a9cd1e0a5dd235f683b7f60ebd9b3269b705fe6634fff22a9991815237e6a044575b836e26c9c7fb7a703c12c9a9708a5f
data/README.md CHANGED
@@ -45,7 +45,7 @@ Usage:
45
45
  jwtear <OPTIONS>
46
46
 
47
47
  Example:
48
- jwtear --generate-token --header '{"typ":"JWT","alg":" "}' --payload '{"login":"admin"}' --key 'P@ssw0rd!'
48
+ jwtear --generate-token --header '{"typ":"JWT","alg":"HS256"}' --payload '{"login":"admin"}' --key 'P@ssw0rd!'
49
49
  jwtear --generate-sig --header '{"typ":"JWT","alg":"HS256"}' --payload '{"login":"admin"}' --key 'P@ssw0rd!'
50
50
  jwtear --parse 'eyJwI...6IfJ9.kxrMS...MjAMm.zEybN...TU2Njk3ZmE3OA'
51
51
 
data/bin/jwtear CHANGED
@@ -22,21 +22,21 @@ option_parser.banner = "#{"JWTear".bold} - Parse, create and manipulate JWT toke
22
22
  option_parser.set_summary_indent ' '
23
23
  option_parser.separator "\nHelp menu:".underline
24
24
  option_parser.on('-p', '--parse JWT_TOKEN' , 'Parse JWT token') {|v| options[:parse] = v}
25
- option_parser.on('--generate-token', 'Generate JWT token.') {|v| options[:generate_token] = v}
26
- option_parser.on('--generate-sig', 'Generate JWT signature.') {|v| options[:generate_sig] = v}
27
- option_parser.on('--header HEADER',
25
+ option_parser.on('-t', '--generate-token', 'Generate JWT token.') {|v| options[:generate_token] = v}
26
+ option_parser.on('-s', '--generate-sig', 'Generate JWT signature.') {|v| options[:generate_sig] = v}
27
+ option_parser.on('-H', '--header HEADER',
28
28
  'JWT header (JSON format). (required for generate-token and generate-sig)',
29
29
  ' eg. {"typ":"JWT","alg":"HS256"} | Supported algorithms: [HS256, RS512, etc]'
30
30
  ) {|v| options[:header] = v}
31
- option_parser.on('--payload PAYLOAD' ,
31
+ option_parser.on('-P', '--payload PAYLOAD' ,
32
32
  'JWT payload (JSON format). (required for generate-token and generate-sig)',
33
33
  ' eg. {"login":"admin"}'
34
34
  ) {|v| options[:payload] = v}
35
- option_parser.on('--alg ALGORITHM',
35
+ option_parser.on('-g', '--alg ALGORITHM',
36
36
  'Force algorithm type when generating a new token (ignore the one in header). (optional with generate-token)',
37
37
  ' Supported algorithms: [HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512]'
38
38
  ) {|v| options[:alg] = v}
39
- option_parser.on('--key SECRET',
39
+ option_parser.on('-k', '--key SECRET',
40
40
  'Secret Key for symmetric encryption. (required for generate-token and generate-sig. Accept password as a string or a file)',
41
41
  ' eg. P@ssw0rd | eg. public_key.pem'
42
42
  ) {|v| options[:key] = v}
@@ -47,7 +47,7 @@ option_parser.on('--key SECRET',
47
47
  option_parser.on('-h', '--help', 'Show this help message') {puts JWTear::Utils.banner , option_parser; exit!}
48
48
  option_parser.on_tail "\nUsage:\n".underline + "jwtear <OPTIONS>"
49
49
  option_parser.on_tail "\nExample:".underline
50
- option_parser.on_tail %Q{jwtear --generate-token --header #{"'".bold}{"typ":"JWT","alg":" "}#{"'".bold} --payload #{"'".bold}{"login":"admin"}#{"'".bold} --key 'P@ssw0rd!'}
50
+ option_parser.on_tail %Q{jwtear --generate-token --header #{"'".bold}{"typ":"JWT","alg":"HS256"}#{"'".bold} --payload #{"'".bold}{"login":"admin"}#{"'".bold} --key 'P@ssw0rd!'}
51
51
  option_parser.on_tail %Q{jwtear --generate-sig --header #{"'".bold}{"typ":"JWT","alg":"HS256"}#{"'".bold} --payload #{"'".bold}{"login":"admin"}#{"'".bold} --key 'P@ssw0rd!'}
52
52
  option_parser.on_tail %Q{jwtear --parse #{"'".bold}eyJwI...6IfJ9#{'.'.bold}kxrMS...MjAMm#{'.'.bold}zEybN...TU2Njk3ZmE3OA#{"'".bold}\n\n}
53
53
 
@@ -55,6 +55,7 @@ begin
55
55
  option_parser.parse!
56
56
  include JWTear::Utils
57
57
  case
58
+ # parse
58
59
  when options[:parse]
59
60
  jwt = JWTear::JWT.new(options[:parse])
60
61
  jwt_parsed = jwt.parse
@@ -70,9 +71,11 @@ begin
70
71
  puts "[+] ".dark_green + "Signature (envelope segment) - encoded:".bold.underline
71
72
  puts "#{Base64.urlsafe_encode64(jwt.signature)}"
72
73
 
74
+ # checking missing for generate_token
73
75
  when options[:generate_token] && (options[:header] || options[:payload] || options[:key]).nil?
74
76
  puts '[!] '.red + "Missing mandatory switch(es) '--header/--payload/--alg/--key'"
75
77
 
78
+ # checking missing for generate_sig
76
79
  when options[:generate_sig] && (options[:header] || options[:payload] || options[:key]).nil?
77
80
  puts '[!] '.red + "Missing mandatory switch(es) '--header/--payload/--key'"
78
81
 
@@ -112,7 +115,6 @@ rescue OptionParser::InvalidOption => e
112
115
  rescue Exception => e
113
116
  puts "[x] ".red + "Unknown Exception: option parser"
114
117
  puts '[!] '.yellow + 'Please report the issue at: https://github.com/KINGSABRI/jwtear/issues'.underline
115
- puts e.backtrace
116
118
  puts e.backtrace_locations
117
119
  puts e
118
120
  end
@@ -72,6 +72,7 @@ module JWTear
72
72
  #
73
73
  def supported_algorithms
74
74
  {
75
+ None: [],
75
76
  SHA: %w{HS256 HS384 HS512},
76
77
  RSA: %w{RS256 RS384 RS512},
77
78
  ESDSA: %w{ES256 ES384 ES512}
@@ -1,4 +1,8 @@
1
1
  module JWTear
2
+
3
+ # Token
4
+ class InvalidTokenError < Exception; end
5
+
2
6
  # Algorithm Errors
3
7
  class AlgorithmRequiresKeyError < TypeError; end
4
8
  class AlgorithmUnknownError < Exception; end
@@ -8,8 +8,8 @@ module JWTear
8
8
  include JWTear::Utils
9
9
 
10
10
  # @!attribute [rw] token [String] generated or parsed token
11
- # @!attribute [rw] header [String] generated or parsed header
12
- # @!attribute [rw] payload [String] generated or parsed payload
11
+ # @!attribute [rw] header [Hash]
12
+ # @!attribute [rw] payload [Hash]
13
13
  attr_accessor :token, :header, :payload
14
14
  # @!attribute [rw] alg [String] generated or parsed algorithm
15
15
  # @!attribute [rw] key [String] given encryption key
@@ -18,7 +18,7 @@ module JWTear
18
18
  # @!attribute [r] json [JSON] given or parsed json
19
19
  # @!attribute [r] hash [Hash] hash result of parsing given or generated json
20
20
  attr_reader :json, :hash
21
- # @!attribute [r] signature [String] generated or parsed signature
21
+ # @!attribute [r] signature [String] generated or parsed signature.
22
22
  # @!attribute [r] rsa_private [String] generated private private key
23
23
  # @!attribute [r] rsa_public [String] generated or given public key
24
24
  attr_reader :signature, :rsa_private, :rsa_public
@@ -33,27 +33,28 @@ module JWTear
33
33
  #
34
34
  # @param token String
35
35
  def parse(token=@token)
36
+ is_token?(token)
36
37
  _token = token.split('.')
37
- @header = JSON.parse(Base64.urlsafe_decode64(_token[0]))
38
+ @header = JSON.parse(decode(_token[0]))
38
39
  @type, @alg = @header['type'], @header['alg']
39
- @payload = JSON.parse(Base64.urlsafe_decode64(_token[1]))
40
- @signature = Base64.urlsafe_decode64(_token[2]) unless (_token[2].nil? or _token[2].empty?)
40
+ @payload = JSON.parse(decode(_token[1]))
41
+ @signature = decode(_token[2]) unless (_token[2].nil? or _token[2].empty?)
41
42
  set_hash_and_json
42
43
  end
43
44
 
44
45
  # build the hash and Json format from the parsed or generated token
45
46
  def set_hash_and_json
46
- @json = "#{@header.to_json}.#{@payload.to_json}.#{Base64.urlsafe_encode64(@signature, padding: false)}"
47
- @hash = {header: @header, payload: @payload, signature: Base64.urlsafe_encode64(@signature, padding: false)}
47
+ @hash = {header: @header, payload: @payload, signature: encode(@signature)}
48
+ @json = "#{@header.to_json}.#{@payload.to_json}.#{encode(@signature)}"
48
49
  end
49
50
 
50
51
  # generate signature
51
52
  #
52
53
  # @param data [String]. 'Base64.encode(header)'.'Base64.encode(payload)'>
53
- # @param alg [String] supported algorithms: HS256 HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
54
+ # @param alg [String] supported algorithms: @see [Algorithms#supported_algorithms]
54
55
  # @param key String
55
56
  #
56
- # @return [String] the generate signature
57
+ # @return [Self] the generate signature
57
58
  #
58
59
  def generate_sig(data, alg, key)
59
60
  begin
@@ -66,9 +67,9 @@ module JWTear
66
67
  @rsa_private = rsa[:private_key]
67
68
  @signature = rsa[:signature]
68
69
  when /^ES/
69
- ecdsa(data, alg)
70
+ @signature = ecdsa(data, alg)
70
71
  when /none/i
71
- none
72
+ @signature = none
72
73
  else
73
74
  raise AlgorithmUnknownError
74
75
  end
@@ -93,22 +94,24 @@ module JWTear
93
94
  end
94
95
 
95
96
  # generate JWT token
96
- # by default, generate_token uses the given json header to detect the algorithm. But it also accept to ignore than
97
- # and force it to you another algorithm.
97
+ # by default, generate_token uses the given json header to detect the algorithm.
98
+ # But it also accept to ignore that and force it to you another algorithm.
98
99
  #
99
100
  # @return [String] the generated token
100
101
  #
101
102
  def generate_token
102
- @header = JSON.parse(@header) unless @header.is_a?(Hash)
103
- @payload = JSON.parse(@payload) unless @payload.is_a?(Hash)
104
- @alg = @header['alg'] if @alg.nil?
105
- header = Base64.urlsafe_encode64(@header.to_json, padding: false)
106
- payload = Base64.urlsafe_encode64(@payload.to_json, padding: false)
107
- data = "#{header}.#{payload}"
108
- @signature = generate_sig(data, @alg, @key).signature
109
- signature = encode(@signature)
110
- token = [header, payload, signature].join('.')
111
- parse(token)
103
+
104
+ @header = JSON.parse(@header) unless @header.is_a?(Hash)
105
+ @payload = JSON.parse(@payload) unless @payload.is_a?(Hash)
106
+ @alg = @header['alg'] if @alg.nil? # if algorithm not forced, take if from the header
107
+
108
+ header_encoded = encode(@header.to_json)
109
+ payload_encoded = encode(@payload.to_json)
110
+ data = "#{header_encoded}.#{payload_encoded}"
111
+ signature_encoded = encode(generate_sig(data, @alg, @key).signature)
112
+ token = [header_encoded, payload_encoded, signature_encoded].join('.')
113
+
114
+ set_hash_and_json
112
115
 
113
116
  token
114
117
  end
@@ -1,6 +1,17 @@
1
1
  module JWTear
2
2
  module Utils
3
3
 
4
+ # check token format
5
+ def is_token?(token)
6
+ begin
7
+ token_size = token.split('.').size
8
+ raise InvalidTokenError if token_size < 2
9
+ rescue InvalidTokenError
10
+ puts '[!] '.red + "Invalid token: #{token}"
11
+ exit!
12
+ end
13
+ end
14
+
4
15
  def encode(data)
5
16
  Base64.urlsafe_encode64(data, padding: false)
6
17
  end
@@ -9,13 +20,13 @@ module JWTear
9
20
  Base64.urlsafe_decode64(data)
10
21
  end
11
22
 
12
- def encode_header_payload(header, payload)
13
- [header, payload].map {|part| encode part}.join('.')
14
- end
23
+ # def encode_header_payload_signature(header, payload, signature)
24
+ # [header, payload, signature].map {|part| encode part}.join('.')
25
+ # end
15
26
 
16
27
  # JWTear's logo
17
28
  def self.banner
18
- %Q{\n 888888 888 888 88888888888
29
+ %Q{\n 888888 888 888 88888888888
19
30
  "88b 888 o 888 888
20
31
  888 888 d8b 888 888
21
32
  888 888 d888b 888 888 .d88b. 8888b. 888d888
@@ -1,3 +1,3 @@
1
1
  module JWTear
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwtear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - KING SABRI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-11 00:00:00.000000000 Z
11
+ date: 2018-01-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: JWTear, command-line tool and library to parse, create and manipulate
14
14
  JWT tokens for security testing purposes.