2017-11-24 3 views
0

Ich muss ein Json Web Token erstellen und es mit einem asymetrischen RS256-Algorithmus signieren. Der zum Signieren verwendete Schlüssel sollte einem X509-Zertifikat entnommen werden und vom Empfänger mit dem öffentlichen Schlüssel validiert werden..NET: Ungültige Signatur in RS256 signiert JWT

HMAC Verwendung und Passwort funktioniert gut, aber die JWT unten aufgeführt mit dem Code erstellt, produziert constantlyI eine „Invalid Signatur“ bei https://jwt.io

ich durch viele Buchungen hier haben, eine Menge nützliche Hinweise gefunden, aber keine von ihnen löste mein Problem. Vielleicht habe ich noch ein Problem zu verstehen.

Ich weiß, das Paket System.IdentityModel.Tokens.Jwt bietet tatsächlich alles, was ich brauche, aber ich möchte verstehen, was ich falsch mache.

 // Get certificate from local store 
     X509Store store = new X509Store(StoreLocation.CurrentUser); 
     store.Open(OpenFlags.ReadOnly); 
     X509Certificate2 x509Cert = (from X509Certificate2 c in store.Certificates where c.SubjectName.Name == $"CN={userName}" select c).First(); 

     if (x509Cert == null) 
     { 
      return string.Empty; 
     } 

     // Setup header 
     var header = new { typ = "JWT", alg = "RS256" }; 
     var headerEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header))); 

     // Setup payload/claims 
     var payload = new 
     { 
      unique_name = $"{userName}@myCompany.com", 
      role = "User", 
      iss = x509Cert.Issuer, 
      aud = "https://dev.myCompany.com", 
      nbf = (Int32)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds, 
      exp = (Int32)DateTime.Now.AddMinutes(5).Subtract(new DateTime(1970, 1, 1)).TotalSeconds, 
      jti = Guid.NewGuid(), 
      x5t = x509Cert.Thumbprint 
     }; 
     var payloadEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload))); 

     // ... and sign, using the RSACertificateExtensions 
     var rsa = x509Cert.GetRSAPrivateKey(); 
     var signed = rsa.SignData(Encoding.UTF8.GetBytes($"{headerEncoded}.{payloadEncoded}"), 
            HashAlgorithmName.SHA256, 
            RSASignaturePadding.Pss); 

     var signatureEncoded = Convert.ToBase64String(signed); 

     return $"{headerEncoded}.{payloadEncoded}.{signatureEncoded}"; 
    } 
+0

Sorry, übersprang die erste Codezeile – Christian

+0

public static string erstellen (string username) { – Christian

+0

Sie können auf Bearbeiten klicken (direkt unter Ihre Frage), um Ihre Frage zu bearbeiten und die fehlende Zeile hinzuzufügen. Und danach können Sie auch Ihre Kommentare löschen. – jps

Antwort

1

Sie haben einige Fehler Aufbau des Token:

  • Für RS256 Verwendung RSASignaturePadding.Pkcs1 nicht RSASignaturePadding.Pss

  • Es base64url Codierung benötigt wird, nicht base64. Ändern Convert.ToBase64String(bytes) mit


Convert.ToBase64String(bytes) 
     .TrimEnd(padding).Replace('+', '-').Replace('/', '_'); 

Mit static readonly char[] padding = { '=' }; Siehe this

Verwandte Themen