appsup-dart / jose

Javascript Object Signing and Encryption (JOSE) library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Validating jwt token issued by googleapis fails using public certificates

priyashpatil opened this issue · comments

Using firebase auth to generate tokens.. Code below is custom backend server which checks auth token passed by frontend client some code is removed.. But you'll get the idea..

validating token
google's public keys

import 'package:x509/x509.dart';
import 'package:http/http.dart' as http;
import 'package:jose/jose.dart';

var authToken = request.headers['authorization'];
var token = authToken.split(' ')[1];
var tokenHeader = token.split('.').first;
var joseHeader = JoseHeader.fromBase64EncodedString(tokenHeader);

var url = Uri.parse('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com');
var response = await http.get(url);

final key = json.decode(response.body)[joseHeader['kid']];
print(key);

var certificate = await parsePem(key).first as X509Certificate;
print(certificate.publicKey);

var jwk = JsonWebKey.fromCryptoKeys(publicKey: certificate.publicKey);
var keyStore = JsonWebKeyStore()..addKey(jwk);

var jwt = JsonWebToken.unverified(token);
var verified = await jwt.verify(keyStore);
print('verified: $verified');

Terminal output

-----BEGIN CERTIFICATE-----
MIIDHDCCAgSgAwIBAgIIbt4McHrn9f0wDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE
AxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMjEw
NTE2MDkyMDIwWhcNMjEwNjAxMjEzNTIwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl
bi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBANnmbU5+gT1KTIM83+x9b1Rwh50lBk15Uhmbmww3dCBunSON
GJjJGF/Ey0J2bmcTNH5t6aEYa/nGubCpkIvlgOdONuzlkIfWNntHcrZ1ww/JOliO
CjlX13Eu4dMlcDyXKFVbIyVdDBTpy+1p52Dg1pXOT4na2wQkELOjqzBUQGrTbr0t
dt1ZiBsDNlAkh6KlwpCfzQCfUYQytJ1QFEKXTRAXvspVLWt5CIdXyT6f4Girii0e
f6V/E9QmVXi4ldyQpMH3BDP8dgrJE22unuIPOttXPZ0PL0hDwVAmBkLz+sXk5YV5
nOIWN8A1mUT/p6AoQiR9rZ0Z1WeyNYd86BHAltMCAwEAAaM4MDYwDAYDVR0TAQH/
BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ
KoZIhvcNAQEFBQADggEBAFPTcoGNo5HvC+oFfyNQXvok3N8FcuXEiXyP4SOyMfw/
cIIPgBrDcgRDiDxlRd66gI6xAGWD+xJ0IEqXaj+pdGtGDdxlS6ooMzzuOdCGH+ou
9m5cd6W/JS17UMtxYKnS1SaKzarDb3gbqzto3WUhvYJCLrdoKr1bwbW/jfQLIja1
qGyuJET+ezqB/XOSm+PtXqtzKsOuV5KFTkz4KQsjV1ACi/l+qHHtcIo0vBn2z0Zs
2i+7Act0Wdbp2EJLTLSZnoTdvXbf/TF3rmn/PlluE4tU3xQ2EkWUTVEdS1JvkMBY
WJ8wpjJsgjYaSQ8m1MLdfP4wwQgU0DGfwLn49ImT2AA=
-----END CERTIFICATE-----

Instance of 'RsaPublicKeyImpl'
verified: false

Got it working.. I wasn't passing kid

  keys.forEach((key, value) {
    var cert = x509.parsePem(value).first as x509.X509Certificate;
    var publicKey = cert.tbsCertificate.subjectPublicKeyInfo?.subjectPublicKey
        as x509.RsaPublicKey;

    var jwk = jose.JsonWebKey.fromCryptoKeys(publicKey: publicKey, keyId: key);
    keyStore.addKey(jwk);
  });