Search code examples
c#asp.net-coreencryptionjwtjwe

How to encrypt jwt payload in ASP.NET Core 6?


I have this code:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = AuthOptions.ISSUER,
            ValidateAudience = true,
            ValidAudience = AuthOptions.AUDIENCE,
            ValidateLifetime = true,
            IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
            ValidateIssuerSigningKey = true,
         };
});

app.Map("/login/{username}", (string username) => 
{
    var claims = new List<Claim> {new Claim(ClaimTypes.Name, username) };
    var jwt = new JwtSecurityToken(
            issuer: AuthOptions.ISSUER,
            audience: AuthOptions.AUDIENCE,
            claims: claims,
            expires: DateTime.UtcNow.Add(TimeSpan.FromMinutes(2)),
            signingCredentials: new SigningCredentials(AuthOptions.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256));
            
    return new JwtSecurityTokenHandler().WriteToken(jwt);
});

public class AuthOptions
{
    public const string ISSUER = "MyAuthServer"; 
    public const string AUDIENCE = "MyAuthClient"; 
    const string KEY = "mysupersecret_secretsecretsecretkey!123";   

    public static SymmetricSecurityKey GetSymmetricSecurityKey() => 
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(KEY));
}

How do I encrypt the payload data in my token? Perhaps TokenDecryptionKey should be added to options.TokenValidationParameters, but how do I encrypt this token initially?


Solution

  • This is how you can encrypt the payload in a token, so that you don't see it jwt.io but at the same time, you could get data from the payload in the code:

    public class AuthOptions
    {
        public const string ISSUER = "MyAuthServer";
        public const string AUDIENCE = "MyAuthClient";
        const string KEY = "SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS"; //64 symbols
        public static SymmetricSecurityKey GetSymmetricSecurityKey() =>
            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(KEY));
    }
    

    Program.cs:

    builder.Services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
    
                ValidIssuer = AuthOptions.ISSUER,
                ValidAudience = AuthOptions.AUDIENCE,
                IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
                TokenDecryptionKey = AuthOptions.GetSymmetricSecurityKey(),
            };
        });
    

    Controller or another place:

    string CreateJwt(string username)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, username),
        };
    
        var jwtSecurityToken = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
            AuthOptions.ISSUER,
            AuthOptions.AUDIENCE,
            new ClaimsIdentity(claims),
            null,
            expires: DateTime.UtcNow.AddMinutes(5),
            null,
            signingCredentials: new SigningCredentials(AuthOptions.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256),
            encryptingCredentials: new EncryptingCredentials(AuthOptions.GetSymmetricSecurityKey(), JwtConstants.DirectKeyUseAlg, SecurityAlgorithms.Aes256CbcHmacSha512)
        );
    
        return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
    }