diff --git a/src/nHash/Providers/JsonBeautifier.cs b/src/nHash/Providers/JsonBeautifier.cs new file mode 100644 index 0000000..f737d06 --- /dev/null +++ b/src/nHash/Providers/JsonBeautifier.cs @@ -0,0 +1,24 @@ +using System.Text.Json; + +namespace nHash.Providers; + +public class JsonBeautifier +{ + private readonly JsonSerializerOptions _serializerOptions; + + public JsonBeautifier() + { + _serializerOptions = new JsonSerializerOptions + { + WriteIndented = true, + PropertyNameCaseInsensitive = true + }; + } + + public string Set(string text) + { + var jsonElement = JsonDocument.Parse(text).RootElement; + var prettyJson = JsonSerializer.Serialize(jsonElement, _serializerOptions); + return prettyJson; + } +} \ No newline at end of file diff --git a/src/nHash/SubFeatures/Encodes/JwtTokenDecodeFeature.cs b/src/nHash/SubFeatures/Encodes/JwtTokenDecodeFeature.cs index a47fd65..d454f6a 100644 --- a/src/nHash/SubFeatures/Encodes/JwtTokenDecodeFeature.cs +++ b/src/nHash/SubFeatures/Encodes/JwtTokenDecodeFeature.cs @@ -1,4 +1,7 @@ -using System.IdentityModel.Tokens.Jwt; +using System.Text; +using System.Text.Json.Nodes; +using System.Web; +using nHash.Providers; namespace nHash.SubFeatures.Encodes; @@ -17,7 +20,7 @@ public JwtTokenDecodeFeature() private Command GetFeatureCommand() { - var command = new Command("jwt", "JWT token decode") + var command = new Command("jwt", "JWT token decode (Comply with GDPR rules)") { _noWriteInformation }; @@ -29,17 +32,30 @@ private Command GetFeatureCommand() private static void DecodeJwtToken(string text, bool noWriteInformation) { - var tokenHandler = new JwtSecurityTokenHandler(); - var jwt = tokenHandler.ReadJwtToken(text); + var parts = text.Split('.'); + var header = parts[0]; + var payload = parts[1]; + //var signature = parts[2]; + + + var decodedHeader = HttpUtility.UrlDecode(Encoding.UTF8.GetString(Convert.FromBase64String(header))); + payload = payload.PadRight(payload.Length + (payload.Length * 3) % 4, '='); + var decodedPayload = HttpUtility.UrlDecode(Encoding.UTF8.GetString(Convert.FromBase64String(payload))); + + //Console.WriteLine("JWT payload: " + decodedPayload); + var jsonBeautifier = new JsonBeautifier(); + var prettyHeader = jsonBeautifier.Set(decodedHeader); + var prettyPayload = jsonBeautifier.Set(decodedPayload); - Console.WriteLine(); Console.WriteLine("Header: (ALGORITHM & TOKEN TYPE)"); - WriteHeaders(jwt); - + Console.WriteLine(prettyHeader); + Console.WriteLine(); Console.WriteLine("Payload: (DATA)"); - WritePayload(jwt); + Console.WriteLine(prettyPayload); + + //WritePayload(jwt); if (noWriteInformation) { @@ -48,10 +64,12 @@ private static void DecodeJwtToken(string text, bool noWriteInformation) Console.WriteLine(); Console.WriteLine("Summary:"); - WriteSummary(jwt); + WriteSummary(decodedHeader, decodedPayload); + //Console.WriteLine("JWT algorithm: " + JsonObject.Parse(decodedHeader)["alg"]); + //jwtObject.has } - private static void WriteHeaders(JwtSecurityToken jwt) + /*private static void WriteHeaders(JwtSecurityToken jwt) { foreach (var header in jwt.Header) { @@ -65,45 +83,64 @@ private static void WritePayload(JwtSecurityToken jwt) { Console.WriteLine(" " + claim.Key + ": " + claim.Value); } - } + }*/ - private static void WriteSummary(JwtSecurityToken jwt) + private static void WriteSummary(string header, string payload) { - // Get algorithm and other data from JWT token - Console.WriteLine(" Algorithm: " + jwt.Header.Alg); - if (!string.IsNullOrWhiteSpace(jwt.Issuer)) + var jwtObjectHeader = JsonNode.Parse(header); + if (jwtObjectHeader is null) { - Console.WriteLine(" Issuer: " + jwt.Issuer); + return; + } + + var algorithm = jwtObjectHeader["alg"]; + if (algorithm is not null) + { + Console.WriteLine(" Algorithm: " + algorithm); + } + + var jwtObjectPayload = JsonNode.Parse(payload); + if (jwtObjectPayload is null) + { + return; } - if (jwt.IssuedAt != DateTime.MinValue) + var issuer = jwtObjectPayload["iss"]; + if (issuer is not null) { - Console.WriteLine(" Issued at: " + jwt.IssuedAt); + Console.WriteLine(" Issuer: " + issuer); } - if (!string.IsNullOrWhiteSpace(jwt.Id)) + var issuedAt = jwtObjectPayload["iat"]; + if (issuedAt is not null) { - Console.WriteLine(" Id: " + jwt.Id); + var issueValue = Convert.ToInt64(issuedAt.ToString()); + Console.WriteLine(" Issued at: " + DateTimeOffset.FromUnixTimeSeconds(issueValue).DateTime); } - if (jwt.Audiences.Any()) + var id = jwtObjectPayload["id"]; + if (id is not null) { - Console.WriteLine(" Audience: " + string.Join(", ", jwt.Audiences)); + Console.WriteLine(" Id: " + id); } - if (!string.IsNullOrWhiteSpace(jwt.Subject)) + var audience = jwtObjectPayload["aud"]; + if (audience is not null) { - Console.WriteLine(" Subject: " + jwt.Subject); + Console.WriteLine(" Audience: " + audience); } - if (!string.IsNullOrWhiteSpace(jwt.Actor)) + var subject = jwtObjectPayload["sub"]; + if (subject is not null) { - Console.WriteLine(" Actor: " + jwt.Actor); + Console.WriteLine(" Subject: " + subject); } - if (jwt.ValidTo != DateTime.MinValue) + var expirationAt = jwtObjectPayload["exp"]; + if (expirationAt is not null) { - Console.WriteLine(" Expiration: " + jwt.ValidTo); + var expirationValue = Convert.ToInt64(expirationAt.ToString()); + Console.WriteLine(" Expiration: " + DateTimeOffset.FromUnixTimeSeconds(expirationValue).DateTime); } } } \ No newline at end of file diff --git a/src/nHash/SubFeatures/Texts/JsonFeature.cs b/src/nHash/SubFeatures/Texts/JsonFeature.cs new file mode 100644 index 0000000..0ea2f52 --- /dev/null +++ b/src/nHash/SubFeatures/Texts/JsonFeature.cs @@ -0,0 +1,6 @@ +namespace nHash.SubFeatures.Texts; + +public class JsonFeature +{ + +} \ No newline at end of file diff --git a/src/nHash/nHash.csproj b/src/nHash/nHash.csproj index 8121f2d..9df4860 100644 --- a/src/nHash/nHash.csproj +++ b/src/nHash/nHash.csproj @@ -3,7 +3,7 @@ Exe net7.0 - 1.3 + 1.3.2 enable enable latestmajor @@ -16,7 +16,5 @@ - -