Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

264
Visualizações
Validación manual de tokens de Firebase Auth

Estoy tratando de usar trabajadores de Cloudflare para realizar acciones autenticadas.

Estoy usando firebase para la autenticación y tengo acceso a los tokens de acceso, pero dado que firebase-admin usa módulos nodejs, no puede funcionar en la plataforma, así que me quedo validando manualmente el token.

He estado intentando autenticarme con Crypto API y finalmente logré importar la clave pública, firmar el token para verificar si es válido, pero sigo obteniendo FALSO. Estoy luchando por descubrir por qué siempre devuelve falso para la validez.

La clave criptográfica que importé viene como tipo "secreto" donde esperaría que fuera "público".

Cualquier pensamiento o ayuda sería enorme. He estado golpeando mi cabeza contra una mesa durante los últimos días tratando de resolver esto.

Esto es lo que tengo hasta ahora:

 function _utf8ToUint8Array(str) { return Base64URL.parse(btoa(unescape(encodeURIComponent(str)))) } class Base64URL { static parse(s) { return new Uint8Array(Array.prototype.map.call(atob(s.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '')), c => c.charCodeAt(0))) } static stringify(a) { return btoa(String.fromCharCode.apply(0, a)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_') } } export async function verify(userToken: string) { let jwt = decodeJWT(userToken) var jwKey = await fetchPublicKey(jwt.header.kid); let publicKey = await importPublicKey(jwKey); var isValid = await verifyPublicKey(publicKey, userToken); console.log('isValid', isValid) // RETURNS FALSE return isValid; } function decodeJWT(jwtString: string): IJWT { // @ts-ignore const jwt: IJWT = jwtString.match( /(?<header>[^.]+)\.(?<payload>[^.]+)\.(?<signature>[^.]+)/ ).groups; // @ts-ignore jwt.header = JSON.parse(atob(jwt.header)); // @ts-ignore jwt.payload = JSON.parse(atob(jwt.payload)); return jwt; } async function fetchPublicKey(kid: string) { var key: any = await (await fetch('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com')).json(); key = key[kid]; key = _utf8ToUint8Array(key) return key; } function importPublicKey(jwKey) { return crypto.subtle.importKey('raw', jwKey, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']); } async function verifyPublicKey(publicKey: CryptoKey, token: string) { const tokenParts = token.split('.') let res = await crypto.subtle.sign({ name: 'HMAC', hash: { name: 'SHA-256' } }, publicKey, _utf8ToUint8Array(tokenParts.slice(0, 2).join('.'))) return Base64URL.stringify(new Uint8Array(res)) === tokenParts[2]; }
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Tenga en cuenta que puede obtener los jwks desde el extremo no documentado https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com .

 async function fetchPublicKey(kid) { const result = await ( await fetch( "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com" ) ).json(); return result.keys.find((key) => key.kid === kid); }

Usando la clave (llamada jwk a continuación), puede verificar la firma:

 const encoder = new TextEncoder(); const data = encoder.encode([token.raw.header, token.raw.payload].join(".")); const signature = new Uint8Array( Array.from(token.signature).map((c) => c.charCodeAt(0)) ); const key = await crypto.subtle.importKey( "jwk", jwk, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, false, ["verify"] ); return crypto.subtle.verify("RSASSA-PKCS1-v1_5", key, signature, data);
about 4 years ago · Juan Pablo Isaza Relatório

0

Hay algunos problemas con su código:

  1. La URL a la que llama para obtener claves públicas devuelve una lista de certificados x509. Estas no son claves públicas utilizadas para verificar firmas. ¿Estás seguro de que no tienes acceso directo a las claves públicas? Parece que es posible obtener la información de la clave pública de un certificado x509 (como se describe aquí: Extraer la clave pública PEM del certificado X.509 ), aunque no estoy seguro de si eso es posible de un trabajador de Cloudflare.

  2. En importPublicKey , le está diciendo al método de import que la clave está en formato sin formato y que es una clave HMAC . Esto significa que crypto trata su clave como una clave HMAC simétrica, no como una clave pública. De acuerdo con los documentos: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#subjectpublickeyinfo , debe usar el formato spki , ya que este es el que importa una clave pública. Debería saber por adelantado si el token de acceso JWT está firmado con el algoritmo RSA o Elliptic Curve. (por ejemplo, verifique el reclamo del encabezado alg )

  3. Está utilizando el método de sign para verificar la firma. Así no es cómo funciona. Debe usar el método de verify de crypto.subtle y este método verificará la firma por usted.

Creo que no debería intentar verificar los JWT manualmente, ya que lo más probable es que lo haga mal (y cree problemas de seguridad para su aplicación). Debería usar bibliotecas que se ocupen de la verificación de firmas JWT. Será mucho más fácil para ti y más seguro para tu aplicación. Una cosa que debe averiguar es de dónde debe tomar la clave pública.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda