Web API  

JWT Encoder ASP.NET C# Using (HS256)

Introduction

JSON Web Token (JWT) is an open standard defined in RFC 7519 used for securely transmitting information between parties as a JSON object. JWT is widely used for authentication and authorization in modern API-based systems.

This article explains:

  • What JWT is

  • How JWT encoding works (Header + Payload + Signature)

  • Real-time example using HS256

  • How to generate JWT in ASP.NET C#

  • How to create a reusable GenerateJwtToken method

  • How to call an API using the generated token

  • How to handle API responses (array or object) with proper error handling

What is JWT?

JWT (JSON Web Token) is a compact, URL-safe string made of three parts:

Header.Payload.Signature

Example JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0
.
KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30

JWT Structure Explained

JWT contains three components:

  • Header

  • Payload

  • Signature

Header – Algorithm & Token Type

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg → Signing algorithm (HS256 in this case)

  • typ → Token type (JWT)

HS256 means HMAC with SHA-256 using a secret key.

Payload – Data (Claims)

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}

Common claims:

  • sub → Subject (User ID)

  • name → User name

  • admin → Role

  • iat → Issued at time

Important: Payload is encoded, not encrypted.

Signature – Secret

Secret:

a-string-secret-at-least-256-bits-long

Signature is created using:

HMACSHA256(
Base64UrlEncode(header) + "." +
Base64UrlEncode(payload),
secret
)

Final JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0
.
KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30

Real-Time ASP.NET C# Implementation (HS256)

Required Libraries

  • Newtonsoft.Json

  • System.IdentityModel.Tokens.Jwt

  • Microsoft.IdentityModel.Tokens

Common JWT Libraries:

  • Java → jjwt

  • .NET → System.IdentityModel.Tokens.Jwt

  • Node.js → jsonwebtoken

  • Python → PyJWT

Step 1: Create a Model Based on Payload

public class JwtRequestModel
{
    public string sub { get; set; }
    public string name { get; set; }
    public bool admin { get; set; }
    public long iat { get; set; }
}

Usage:

var requestObj = new JwtRequestModel
{
    sub = "1234567890",
    name = "John Doe",
    admin = true,
    iat = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};

Step 2: Reusable GenerateJwtToken Method

You can generate one token and reuse it for multiple API calls if it is still valid.

private string GenerateJwtToken<T>(T requestObj)
{
    var header = new { alg = "HS256", typ = "JWT" };

    string headerBase64 = Base64UrlEncode(
        Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header)));

    string payloadBase64 = Base64UrlEncode(
        Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(requestObj)));

    string unsignedToken = headerBase64 + "." + payloadBase64;

    using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)))
    {
        string signature = Base64UrlEncode(
            hmac.ComputeHash(Encoding.UTF8.GetBytes(unsignedToken)));

        return unsignedToken + "." + signature;
    }
}

Base64Url Encode Method:

private static string Base64UrlEncode(byte[] input)
{
    return Convert.ToBase64String(input)
        .TrimEnd('=')
        .Replace('+', '-')
        .Replace('/', '_');
}

Generate Token:

string jwtToken = GenerateJwtToken(requestObj);
LogError("JWT GENERATED : " + jwtToken);

Step 3: Call API Using JWT Token

using (var client = new HttpClient())
{
    client.Timeout = TimeSpan.FromSeconds(30);

    var content = new StringContent(jwtToken, Encoding.UTF8, "text/plain");

    HttpResponseMessage response = await client.PostAsync(apiUrl, content);

    LogError("API STATUS: " + response.StatusCode);

    if (!response.IsSuccessStatusCode)
    {
        ShowApiError("HTTP Error: " + response.StatusCode);
        return;
    }

    string responseData = await response.Content.ReadAsStringAsync();
    LogError("API RESPONSE: " + responseData);
}

Step 4: Handle API Response (Array or Object)

try
{
    JToken parsedJson = JToken.Parse(responseData);

    if (parsedJson.Type == JTokenType.Array)
    {
        var dataArray = parsedJson.ToObject<List<object>>();
        LogError("Array Response Count: " + dataArray.Count);
    }
    else if (parsedJson.Type == JTokenType.Object)
    {
        var dataObject = parsedJson.ToObject<Dictionary<string, object>>();
        LogError("Object Response Keys: " + dataObject.Count);
    }
}
catch (JsonReaderException ex)
{
    LogError("Invalid JSON: " + ex.Message);
}
catch (Exception ex)
{
    LogError("General Error: " + ex.Message);
}

Full Try-Catch with API Call

try
{
    string jwtToken = GenerateJwtToken(requestObj);

    using (var client = new HttpClient())
    {
        client.Timeout = TimeSpan.FromSeconds(30);

        var content = new StringContent(jwtToken, Encoding.UTF8, "text/plain");

        HttpResponseMessage response = await client.PostAsync(apiUrl, content);

        if (!response.IsSuccessStatusCode)
        {
            ShowApiError("HTTP Error: " + response.StatusCode);
            return;
        }

        string responseData = await response.Content.ReadAsStringAsync();

        JToken parsedJson = JToken.Parse(responseData);

        if (parsedJson.Type == JTokenType.Array)
        {
            // Handle array
        }
        else
        {
            // Handle object
        }
    }
}
catch (TaskCanceledException)
{
    ShowApiError("Request Timeout");
}
catch (HttpRequestException ex)
{
    ShowApiError("HTTP Request Error: " + ex.Message);
}
catch (Exception ex)
{
    ShowApiError("Unexpected Error: " + ex.Message);
}

Important Notes

  • You can generate one token and reuse it across multiple API calls if expiration is valid.

  • Always store secret key securely (AppSettings or environment variable).

  • Always use HTTPS.

  • Add expiration (exp claim) in production.

  • Do not store sensitive data in payload.

Real-World Example Scenario

Imagine a financial payout system:

  • Your system generates a JWT using merchant ID and timestamp.

  • The token is signed with HS256.

  • The token is sent to the payout API.

  • The payout server validates signature using the shared secret.

  • If valid → request processed.

  • If invalid → rejected.

This ensures secure and tamper-proof API communication.

Conclusion

JWT using HS256 in ASP.NET C# is:

  • Secure

  • Stateless

  • Scalable

  • Easy to integrate

By creating a reusable GenerateJwtToken method, you can generate a single conversation token and use it efficiently across multiple API calls.