How to encrypt JWT security token?

后端 未结 3 1574
梦如初夏
梦如初夏 2020-12-13 02:54

I need to secure my web-token with signing and encryption. I wrote the next lines of code:

var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescrip         


        
相关标签:
3条回答
  • 2020-12-13 03:29

    I know this an old post, but I am adding my answer in case if someone is still searching for the answer.

    This issue is addressed in Microsoft.IdentityModel.Tokens version 5.1.3. There is an overloaded method available in the CreateJwtSecurityToken function which accepts the encrypting credentials to encrypt the token.

    If the receiver does not validate the signature and tries to read JWT as is then the claims are empty. Following is the code snippet:

    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;
    
    const string sec = "ProEMLh5e_qnzdNUQrqdHPgp";
    const string sec1 = "ProEMLh5e_qnzdNU";
    var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec));
    var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1)); 
    
    var signingCredentials = new SigningCredentials(
        securityKey,
        SecurityAlgorithms.HmacSha512);
    
    List<Claim> claims = new List<Claim>()
    {
        new Claim("sub", "test"),
    };
    
    var ep = new EncryptingCredentials(
        securityKey1,
        SecurityAlgorithms.Aes128KW,
        SecurityAlgorithms.Aes128CbcHmacSha256);
    
    var handler = new JwtSecurityTokenHandler();
    
    var jwtSecurityToken = handler.CreateJwtSecurityToken(
        "issuer",
        "Audience",
        new ClaimsIdentity(claims),
        DateTime.Now,
        DateTime.Now.AddHours(1),
        DateTime.Now,
        signingCredentials,
        ep);
    
    
    string tokenString = handler.WriteToken(jwtSecurityToken);
    
    // Id someone tries to view the JWT without validating/decrypting the token,
    // then no claims are retrieved and the token is safe guarded.
    var jwt = new JwtSecurityToken(tokenString);
    

    And here is the code to validate/decrypt the token:

    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;
    
    const string sec = "ProEMLh5e_qnzdNUQrqdHPgp";
    const string sec1 = "ProEMLh5e_qnzdNU";
    var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec));
    var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1));
    
    // This is the input JWT which we want to validate.
    string tokenString = string.Empty;
    
    // If we retrieve the token without decrypting the claims, we won't get any claims
    // DO not use this jwt variable
    var jwt = new JwtSecurityToken(tokenString);
    
    // Verification
    var tokenValidationParameters = new TokenValidationParameters()
    {
        ValidAudiences = new string[]
        {
            "536481524875-glk7nibpj1q9c4184d4n3gittrt8q3mn.apps.googleusercontent.com"
        },
        ValidIssuers = new string[]
        {
            "https://accounts.google.com"
        },
        IssuerSigningKey = securityKey,
        // This is the decryption key
        TokenDecryptionKey = securityKey1
    };
    
    SecurityToken validatedToken;
    var handler = new JwtSecurityTokenHandler();
    
    handler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken);
    
    0 讨论(0)
  • 2020-12-13 03:39

    My understanding is that Microsoft's JWT implementation doesn't currently support encryption (only signing).

    0 讨论(0)
  • 2020-12-13 03:47

    Try the following example

    Updated Jul-2019: .NET Core, Asp.net Core

    1.Create JWT

    private string CreateJwt(string sub, string jti, string issuer, string audience)
    {
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, sub),
            new Claim(JwtRegisteredClaimNames.Jti, jti),
        };
    
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS"));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var encryptingCredentials = new EncryptingCredentials(key, JwtConstants.DirectKeyUseAlg, SecurityAlgorithms.Aes256CbcHmacSha512);
    
        var jwtSecurityToken = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
            issuer,
            audience,
            new ClaimsIdentity(claims),
            null,
            expires: DateTime.UtcNow.AddMinutes(5),
            null,
            signingCredentials: creds,
            encryptingCredentials: encryptingCredentials
            );
        var encryptedJWT = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
    
        return encryptedJWT;
    }
    

    2.Add to ConfigureServices(IServiceCollection services) in Startup.cs

        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 = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Issuer"),
            ValidAudience = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Audience"),
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
            TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
            ClockSkew = TimeSpan.FromMinutes(0),
        };
    });
    
    0 讨论(0)
提交回复
热议问题