2016-03-23 5 views
6

Ich habe ein Token, eine Datei mit einem öffentlichen Schlüssel, und ich möchte die Signatur überprüfen. Ich habe versucht, Signatur basierend auf this zu überprüfen.C# Wie kann ich die Signatur JWT verifizieren?

decodedCrypto und decodedSignature stimmen jedoch nicht überein.

Hier ist mein Code:

public static string Decode(string token, string key, bool verify) 
    { 
     var parts = token.Split('.'); 
     var header = parts[0]; 
     var payload = parts[1]; 
     byte[] crypto = Base64UrlDecode(parts[2]); 

     var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header)); 
     var headerData = JObject.Parse(headerJson); 
     var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload)); 
     var payloadData = JObject.Parse(payloadJson); 

     if (verify) 
     { 
      var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload)); 
      var keyBytes = Encoding.UTF8.GetBytes(key); 
      var algorithm = (string)headerData["alg"]; 
      var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign); 
      var decodedCrypto = Convert.ToBase64String(crypto); 
      var decodedSignature = Convert.ToBase64String(signature); 

      if (decodedCrypto != decodedSignature) 
      { 
       throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature)); 
      } 
     } 

     return payloadData.ToString(); 
    } 

ich bin sicher, dass die Unterschrift von Token gültig ist. Ich versuche, auf https://jwt.io/ zu überprüfen, und es zeigte, dass die Signatur verifiziert. Also das Problem ist der Algorithmus zu verschlüsseln, zu dekodieren.

Gibt es jemanden, der dieses Problem lösen kann? Der Algorithmus ist RS256

enter image description here

Antwort

4

Ich habe endlich eine Lösung von meinem Kollegen bekommen.

Für diejenigen, die das gleiche Problem haben, versuchen, meinen Code:

public static string Decode(string token, string key, bool verify = true) 
     { 
      string[] parts = token.Split('.'); 
      string header = parts[0]; 
      string payload = parts[1]; 
      byte[] crypto = Base64UrlDecode(parts[2]); 

      string headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header)); 
      JObject headerData = JObject.Parse(headerJson); 

      string payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload)); 
      JObject payloadData = JObject.Parse(payloadJson); 

      if (verify) 
      { 
       var keyBytes = Convert.FromBase64String(key); // your key here 

       AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes); 
       RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter; 
       RSAParameters rsaParameters = new RSAParameters(); 
       rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned(); 
       rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned(); 
       RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
       rsa.ImportParameters(rsaParameters); 

       SHA256 sha256 = SHA256.Create(); 
       byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + '.' + parts[1])); 

       RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa); 
       rsaDeformatter.SetHashAlgorithm("SHA256"); 
       if (!rsaDeformatter.VerifySignature(hash, FromBase64Url(parts[2]))) 
        throw new ApplicationException(string.Format("Invalid signature")); 
      } 

      return payloadData.ToString(); 
     } 

Es funktioniert für mich. Der Algorithmus ist RS256.

2

Wie wäre es JwtSecurityTokenHandler mit? es könnte wie folgt aussehen:

public bool ValidateToken(string token, byte[] secret) 
{ 
    var tokenHandler = new JwtSecurityTokenHandler(); 

    var validationParameters = new TokenValidationParameters 
    { 
     ValidateIssuerSigningKey = true, 
     IssuerSigningToken = new BinarySecretSecurityToken(secret) 
    }; 

    SecurityToken validatedToken; 
    try 
    { 
     tokenHandler.ValidateToken(token, validationParameters, out validatedToken); 
    } 
    catch (Exception) 
    { 
     return false; 
    } 

    return validatedToken != null; 
} 

Beachten Sie, ich es nicht getestet, aber wir benutzten

+0

Was ist "BinarySecretSecurityToken" hier? Kein Hinweis hier – anhtv13

+0

@ANguyen: https://msdn.microsoft.com/en-us/library/system.servicemodel.security.tokens.binarysecretsecuritytoken(v=vs.110).aspx – Helikaon

+0

Es ist ein Teil von 'IdentityModel' Bibliothek . –

0

byte[] crypto = Base64UrlDecode(parts[2]);

In dieser Linie sind Sie base64 eine ähnliche Umsetzung in einem der Projekte Dekodierung Signatur Teil von JWT Token, aber wie ich weiß, dass Teil nicht Base64 codiert ist. Bitte versuchen Sie diesen Code. (Ich habe unnötige Zeilen auskommentiert)

public static string Decode(string token, string key, bool verify) 
{ 
    var parts = token.Split('.'); 
    var header = parts[0]; 
    var payload = parts[1]; 
    // byte[] crypto = Base64UrlDecode(parts[2]); 
    var jwtSignature = parts[2]; 

    var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header)); 
    var headerData = JObject.Parse(headerJson); 
    var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload)); 
    var payloadData = JObject.Parse(payloadJson); 

    if (verify) 
    { 
     var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload)); 
     var keyBytes = Encoding.UTF8.GetBytes(key); 
     var algorithm = (string)headerData["alg"]; 
     var computedJwtSignature = Encoding.UTF8.GetString(HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign)); 
     // var decodedCrypto = Convert.ToBase64String(crypto); 
     // var decodedSignature = Convert.ToBase64String(signature); 

     if (jwtSignature != computedJwtSignature) 
     { 
      throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature)); 
     } 
    } 

    return payloadData.ToString(); 
} 
+0

computedJwtSignature returns "{3R4p/go1G # i" und sie nicht übereinstimmen. Mein Algorithmus ist RS256 – anhtv13

+0

Was gibt diese Zeile zurück?(Wert und Typ bitte) 'HashAlgorithms [GetHashAlgorithm (Algorithmus)] (keyBytes, bytesToSign)' –

+0

es ist {byte [32]} – anhtv13

4

Ich weiß, dass dies ein alter Thread, aber ich könnte recommended Sie this library statt Schreiben auf eigene Faust zu verwenden. Es hat einige gute Dokumentation, um loszulegen. Verwende es ohne irgendwelche Probleme.

Verwandte Themen