2013-08-14 28 views
17

Ho bisogno di proteggere il mio token web con firma e crittografia. Ho scritto i prossimi righe di codice:Come crittografare il token di sicurezza JWT?

var tokenHandler = new JwtSecurityTokenHandler(); 
var tokenDescriptor = new SecurityTokenDescriptor 
{ 
     Subject = new ClaimsIdentity(new[] 
     { 
      new Claim(ClaimTypes.Name, owner.Name), 
      new Claim(ClaimTypes.Role, owner.RoleClaimType), 
      new Claim("custom claim type", "custom content") 
     }), 
     TokenIssuerName = "self", 
     AppliesToAddress = "http://www.example.com", 
     Lifetime = new Lifetime(now, now.AddSeconds(60 * 3)), 
     EncryptingCredentials = new X509EncryptingCredentials(new X509Certificate2(cert)), 
     SigningCredentials = new X509SigningCredentials(cert1) 
}; 
var token = (JwtSecurityToken)tokenHandler.CreateToken(tokenDescriptor);    
var tokenString = tokenHandler.WriteToken(token); 

Quindi, io sto usando alcuni certificati, generate con makecert.exe. Poi ho letto stringa di token con un altro JwtSecurityTokenHandler:

var tokenHandlerDecr = new JwtSecurityTokenHandler(); 
var tok = tokenHandlerDecr.ReadToken(tokenString); 

e Token contenuto non è crittografato (posso vedere JSON in tok variabile sotto debugger). Che cosa sto facendo di sbagliato? Come crittografare i dati del token?

risposta

5

La mia comprensione è che l'implementazione JWT di Microsoft attualmente non supporta la crittografia (solo firma).

+0

Se è così, vorrei davvero apprezzare se potesse fornirmi qualche link su questo argomento. –

+0

Ho esplorato questa estensione e sembra che tu abbia ragione - la crittografia non è ancora supportata. Grazie! –

+0

È ancora così? –

13

Conosco questo vecchio post, ma aggiungo la mia risposta nel caso in cui qualcuno stia ancora cercando la risposta.

Questo problema viene risolto in Microsoft.IdentityModel.Tokens version 5.1.3. È disponibile un metodo sovraccarico nella funzione CreateJwtSecurityToken che accetta le credenziali di crittografia per crittografare il token.

Se il destinatario non convalida la firma e prova a leggere JWT come è, le attestazioni sono vuote. Di seguito è riportato il frammento di codice:

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); 

Ed ecco il codice per convalidare/decodificare il 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

come decrittografare il token in quanto non è possibile passare la chiave durante la convalida del token? –

+1

@SangSuantak TokenValidationParameters ha la proprietà TokenDecryptionKey. Il validatore utilizza internamente questa proprietà per decrittografare il token. Ho aggiornato la mia risposta per includere la parte di decodifica – Amey

+0

grazie per l'aggiornamento –