无法验证来自 AWS ALB 身份验证的 JWT

A4T*_*eok 5 elixir amazon-web-services jwt

我正在使用JOSE 包与 Elixir 合作。我有一个使用身份验证侦听器规则ALB,我在其中获取的数据x-amzn-oidc-data应该是包含用户声明的 JWT。然而,虽然该值主要采用 JWT 格式,但它是 base64 URL 编码的,但带有填充。因此,JOSE 无法验证大多数传入的令牌(如果令牌到达时没有填充,JOSE 验证它没有问题)。

我想我可以通过简单地=从标头、有效载荷和签名中的令牌中去除字符来解决这个问题,但是似乎没有任何组合可以工作。

我已经使用 jwt.io 尝试调试令牌,并且它会抱怨如果我尝试=从有效负载中删除字符(仅?),签名会变得无效。但是,我尝试使用Python JOSE 库Javascript JOSE 库验证令牌,并且两者都可以。尽管如此,如果我从有效负载中去除填充字符,这两个库都会告诉我签名验证失败。我必须把它留在签名中才能通过。

有没有办法将此令牌转换为不包含填充的格式,并且可以通过 Elixir JOSE 包进行验证?我试图对这些库如何在其他库失败时解码令牌进行逆向工程,但我没有任何运气。

仅作为视觉示例,这就是令牌的外观

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZuFqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA
Run Code Online (Sandbox Code Playgroud)

但是 ALB 向我发送了类似的内容(注意负载和签名中添加的填充字符)

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0==.tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZuFqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA==
Run Code Online (Sandbox Code Playgroud)

小智 1

正如您所提到的,您必须保留=签名验证才能成功。

JOSE 库验证失败的原因是它通过解密标头 + 有效负载来重建签名输入,然后再次加密它们(这次省略=字符)。 https://github.com/potatosalad/erlang-jose/blob/main/src/jws/jose_jws.erl#L378

您可以通过手动构建签名输入并直接调用 alg 库来解决这个问题,如下所示:

#data from x-amzn-oidc-data header, key from "https://public-keys.auth.elb." <> aws_region <> ".amazonaws.com/" <> kid

[header, payload, signature] = String.split(data, ".") |> Enum.map(fn part -> :jose_jwa_base64url.decode(part) end)
signing_input = Base.url_encode64(header) <> "." <> Base.url_encode64(payload)
encoded_key = key |> JOSE.JWK.from_pem() |> JOSE.JWK.to_record()
:jose_jws_alg_ecdsa.verify(encoded_key, signing_input, signature, :ES256)
Run Code Online (Sandbox Code Playgroud)