-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
153 lines (138 loc) · 5.77 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System.ComponentModel;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Spectre.Console;
using Spectre.Console.Cli;
using Spectre.Console.Json;
var app = new CommandApp();
app.Configure(config => {
config.SetApplicationName("jwtconsole");
config.AddCommand<ExtractCommand>("extract")
.WithExample("extract","eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c")
.WithExample("extract","eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","--pretty")
.WithExample("extract","eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","-p");
});
app.Run(args);
public class ExtractCommand : Command<ExtractCommand.ExtractSettings>
{
public class ExtractSettings : CommandSettings
{
[Description("The encoded JWT that needs to be decoded.")]
[CommandArgument(0,"<JWT>")]
public string JWT { get; set; }
[Description("Decrypt the JWT (NOT IMPLEMENTED)")]
[CommandOption("-d|--decrypt")]
public bool? Decrypt { get; set; }
[Description("Display the decoded JSON colorized and formatted")]
[CommandOption("-p|--pretty")]
public bool? PrettyPrint { get; set; }
}
public override int Execute(CommandContext context, ExtractSettings settings)
{
AnsiConsole.MarkupLine($"[yellow]Input JWT value[/]");
AnsiConsole.MarkupLine($"[green]{settings.JWT}[/]\n");
if ( settings.Decrypt == true )
{
//check for base 64 encoded
// var isValidBase64 = Convert.TryFromBase64String(settings.JWT, out var j);
var bytes = Convert.FromBase64String(settings.JWT);
}
//jwt decode
var jwtTokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken token = null;
try
{
token = jwtTokenHandler.ReadJwtToken(settings.JWT);
}
catch (System.Exception)
{
AnsiConsole.MarkupLine($"[red]Unable to parse JWT (Invalid JWT)[/]");
return 0;
}
//get the header and payload objects from the token
var jwtHeader = FixInvalidCharacters(token.EncodedHeader);
var jwtPayload = FixInvalidCharacters(token.EncodedPayload);
var jwtSignature = FixInvalidCharacters(token.RawSignature);
//decode base64 encoded header
//check for valid b64
if ( ! CheckForValidBase64(jwtHeader))
{
//invalid base 64
AnsiConsole.MarkupLine($"[red]Invalid Base64 (HEADER). Trying to add padding[/]");
//try and add padding to base64 string (==) length/divisible by 4
jwtHeader = PadBase64String(jwtHeader);
AnsiConsole.MarkupLine($"[yellow]Updated (PAYLOAD - padded).[/]");
}
var decodedHeaderBytes = Convert.FromBase64String(jwtHeader);
string decodedHeader = System.Text.Encoding.UTF8.GetString(decodedHeaderBytes);
//print token header info
AnsiConsole.MarkupLine($"[yellow]JWT HEADER (Original Encoded)[/]");
AnsiConsole.MarkupLine($"[white]{jwtHeader}[/]");
AnsiConsole.MarkupLine($"[yellow]JWT HEADER (Decoded)[/]");
if ( settings.PrettyPrint == true)
{
var prettyHeaderJson = new JsonText(decodedHeader);
AnsiConsole.Write(prettyHeaderJson);
AnsiConsole.Write("\n\n");
}
else
{
AnsiConsole.MarkupLine($"[white]{decodedHeader}[/]\n");
}
AnsiConsole.MarkupLine($"[yellow]JWT PAYLOAD (Original Encoded)[/]");
AnsiConsole.MarkupLine($"[white]{jwtPayload}[/]\n");
//decode base64 encoded payload
//check and fix the base64 encode
if ( ! CheckForValidBase64(jwtPayload))
{
AnsiConsole.MarkupLine($"[red]Invalid Base64 (PAYLOAD). Trying to add padding[/]");
//try and add padding to base64 string (==)
jwtPayload = PadBase64String(jwtPayload);
AnsiConsole.MarkupLine($"[yellow]Updated (PAYLOAD - padded).[/]");
AnsiConsole.MarkupLine($"[orange1]{jwtPayload}[/]\n");
}
var decodedPayloadBytes = Convert.FromBase64String(jwtPayload);
string decodePayload = System.Text.Encoding.UTF8.GetString(decodedPayloadBytes);
//print payload info
AnsiConsole.MarkupLine($"[yellow]JWT PAYLOAD (Decoded)[/]");
if ( settings.PrettyPrint == true)
{
var prettyPayloadJson = new JsonText(decodePayload);
AnsiConsole.Write(prettyPayloadJson);
}
else
{
AnsiConsole.MarkupLine($"[white]{decodePayload}[/]\n");
}
return 0;
}
public bool CheckForValidBase64(string Base64Item)
{
if ( Base64Item.Replace(" ","").Length % 4 == 0 )
{
return true;
}
else
{
return false;
}
}
public string FixInvalidCharacters(string Base64Item)
{
var b64 = Base64Item.Replace("_","/")
.Replace("-","+");
return b64;
}
public string PadBase64String(string Base64Item)
{
//get the remainder left from mod...
var numberToAdd = Base64Item.Length % 4;
//if remainder if greater that two, subtract two as we can
//only add two padding characters
numberToAdd = numberToAdd <= 2 ? numberToAdd : numberToAdd - 2;
//add any padding characters
Base64Item += new string('=',numberToAdd);
return Base64Item;
}
}