Auth0 - 我在哪里可以获得 JWT 签名密钥

Posted

技术标签:

【中文标题】Auth0 - 我在哪里可以获得 JWT 签名密钥【英文标题】:Auth0 - where can I get JWT signing secret 【发布时间】:2021-07-24 07:04:36 【问题描述】:

我是 Auth0 的新手,希望通过 SPA 为前端和 AWS Lambda 为后端实现 Auth0。

有很多关于使用 express-jwtjwks-rsa 或使用 API 网关的 Authorizer 等包验证 Auth0 JWT 令牌的教程,但有没有办法检索 Auth0 密钥 (tokenSecret),所以我可以使用 jwt.verify 方法验证它?

const jwt = require('jsonwebtoken');

jwt.verify(accessToken, tokenSecret, (err, decoded) => 
      tokenError = err;

      decrytedData = decoded;
    );

【问题讨论】:

登录您的 Auth0 帐户。它在您的个人资料中。你必须知道它,你无法找回它。如果可以,这将不再是秘密。 我找不到验证 JWT 的私钥。 【参考方案1】:

您可能使用 Auth0 默认使用的 RSA256 密钥。因此,您不需要 (HMAC) 私钥,而是需要 RSA 公钥。它们也被称为JSON Web Key Set (JWKS)。

Auth0 在以下 URL 公开这些 JWKS:

https://[your_domain].auth0.com/.well-known/jwks.json

响应将如下所示:


    "keys": [
        
            "alg": "RS256",
            "kty": "RSA",
            "use": "sig",
            "x5c": [
                "MIIC+DCCAeCgAwIBAgIJBIGjYW6hFpn2MA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTAeFw0xNjExMjIyMjIyMDVaFw0zMDA4MDEyMjIyMDVaMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnjZc5bm/eGIHq09N9HKHahM7Y31P0ul+A2wwP4lSpIwFrWHzxw88/7Dwk9QMc+orGXX95R6av4GF+Es/nG3uK45ooMVMa/hYCh0Mtx3gnSuoTavQEkLzCvSwTqVwzZ+5noukWVqJuMKNwjL77GNcPLY7Xy2/skMCT5bR8UoWaufooQvYq6SyPcRAU4BtdquZRiBT4U5f+4pwNTxSvey7ki50yc1tG49Per/0zA4O6Tlpv8x7Red6m1bCNHt7+Z5nSl3RX/QYyAEUX1a28VcYmR41Osy+o2OUCXYdUAphDaHo4/8rbKTJhlu8jEcc1KoMXAKjgaVZtG/v5ltx6AXY0CAwEAAaMvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUQxFG602h1cG+pnyvJoy9pGJJoCswDQYJKoZIhvcNAQEFBQADggEBAGvtCbzGNBUJPLICth3mLsX0Z4z8T8iu4tyoiuAshP/Ry/ZBnFnXmhD8vwgMZ2lTgUWwlrvlgN+fAtYKnwFO2G3BOCFw96Nm8So9sjTda9CCZ3dhoH57F/hVMBB0K6xhklAc0b5ZxUpCIN92v/w+xZoz1XQBHe8ZbRHaP1HpRM4M7DJk2G5cgUCyu3UBvYS41sHvzrxQ3z7vIePRA4WF4bEkfX12gvny0RsPkrbVMXX1Rj9t6V7QXrbPYBAO+43JvDGYawxYVvLhz+BJ45x50GFQmHszfY3BR9TPK8xmMmQwtIvLu1PMttNCs7niCYkSiUv2sc2mlq1i3IashGkkgmo="
            ],
            "n": "yeNlzlub94YgerT030codqEztjfU_S6X4DbDA_iVKkjAWtYfPHDzz_sPCT1Axz6isZdf3lHpq_gYX4Sz-cbe4rjmigxUxr-FgKHQy3HeCdK6hNq9ASQvMK9LBOpXDNn7mei6RZWom4wo3CMvvsY1w8tjtfLb-yQwJPltHxShZq5-ihC9irpLI9xEBTgG12q5lGIFPhTl_7inA1PFK97LuSLnTJzW0bj096v_TMDg7pOWm_zHtF53qbVsI0e3v5nmdKXdFf9BjIARRfVrbxVxiZHjU6zL6jY5QJdh1QCmENoejj_ytspMmGW7yMRxzUqgxcAqOBpVm0b-_mW3HoBdjQ",
            "e": "AQAB",
            "kid": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg",
            "x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"
        
    ]

重要的部分是kidx5c。但是,在您可以 verify 您的令牌之前,您需要将 x5c 的值转换为 PEM 格式的 RSA 公钥。有一个库,称为jwk-to-pem。

您可以使用此库将密钥转换为所需的 PEM 格式。以上面的例子为例:

const jwkToPem = require("jwk-to-pem");

const pem = jwkToPem(
    "alg": "RS256",
    "kty": "RSA",
    "use": "sig",
    "x5c": [
        "MIIC+DCCAeCgAwIBAgIJBIGjYW6hFpn2MA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTAeFw0xNjExMjIyMjIyMDVaFw0zMDA4MDEyMjIyMDVaMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnjZc5bm/eGIHq09N9HKHahM7Y31P0ul+A2wwP4lSpIwFrWHzxw88/7Dwk9QMc+orGXX95R6av4GF+Es/nG3uK45ooMVMa/hYCh0Mtx3gnSuoTavQEkLzCvSwTqVwzZ+5noukWVqJuMKNwjL77GNcPLY7Xy2/skMCT5bR8UoWaufooQvYq6SyPcRAU4BtdquZRiBT4U5f+4pwNTxSvey7ki50yc1tG49Per/0zA4O6Tlpv8x7Red6m1bCNHt7+Z5nSl3RX/QYyAEUX1a28VcYmR41Osy+o2OUCXYdUAphDaHo4/8rbKTJhlu8jEcc1KoMXAKjgaVZtG/v5ltx6AXY0CAwEAAaMvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUQxFG602h1cG+pnyvJoy9pGJJoCswDQYJKoZIhvcNAQEFBQADggEBAGvtCbzGNBUJPLICth3mLsX0Z4z8T8iu4tyoiuAshP/Ry/ZBnFnXmhD8vwgMZ2lTgUWwlrvlgN+fAtYKnwFO2G3BOCFw96Nm8So9sjTda9CCZ3dhoH57F/hVMBB0K6xhklAc0b5ZxUpCIN92v/w+xZoz1XQBHe8ZbRHaP1HpRM4M7DJk2G5cgUCyu3UBvYS41sHvzrxQ3z7vIePRA4WF4bEkfX12gvny0RsPkrbVMXX1Rj9t6V7QXrbPYBAO+43JvDGYawxYVvLhz+BJ45x50GFQmHszfY3BR9TPK8xmMmQwtIvLu1PMttNCs7niCYkSiUv2sc2mlq1i3IashGkkgmo="
    ],
    "n": "yeNlzlub94YgerT030codqEztjfU_S6X4DbDA_iVKkjAWtYfPHDzz_sPCT1Axz6isZdf3lHpq_gYX4Sz-cbe4rjmigxUxr-FgKHQy3HeCdK6hNq9ASQvMK9LBOpXDNn7mei6RZWom4wo3CMvvsY1w8tjtfLb-yQwJPltHxShZq5-ihC9irpLI9xEBTgG12q5lGIFPhTl_7inA1PFK97LuSLnTJzW0bj096v_TMDg7pOWm_zHtF53qbVsI0e3v5nmdKXdFf9BjIARRfVrbxVxiZHjU6zL6jY5QJdh1QCmENoejj_ytspMmGW7yMRxzUqgxcAqOBpVm0b-_mW3HoBdjQ",
    "e": "AQAB",
    "kid": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg",
    "x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"
);

这个pem然后可以用来verify你的令牌:

const jwt = require("jsonwebtoken");

jwt.verify(token, pem, (err, decoded) => [...]);

建议:

我能给出的最重要的建议是“缓存”PEM。不要对每个请求都执行此答案中描述的所有步骤。您有多种选择如何“缓存”密钥:

    将 PEM 与您的 Lambda 部署包捆绑在一起(或将它们直接放入代码中)。我不建议这样做,因为如果密钥发生更改,您需要运行另一个部署,但这种情况很少发生,所以这没关系。无论如何,密钥都是公开的,因此这也不是安全问题。 在 Lambda 初始化时下载 JWKS 并将密钥转换为 PEM 格式。然后将其存储在“全局”变量中并在请求之间使用。 将预先计算的 PEM 放在 S3 上并下载 Lambda 初始化等。

我通常会做 #2,但其他也可以。

链接:

    Auth0 Blog: Navigating RS256 and JWKS

【讨论】:

感谢您的惊人回复,我花了数小时寻找不涉及使用 Auth0 的 Express SDK 的 JWT 验证。再次感谢。

以上是关于Auth0 - 我在哪里可以获得 JWT 签名密钥的主要内容,如果未能解决你的问题,请参考以下文章

如何生成用于 com.auth0 java-jwt 的 RSA 密钥?

SpringBoot整合JWT实现登录认证

为啥 JSON Web Token (JWT) 在不知道密钥的情况下解密

jwt.io 说签名验证即使没有提供密钥

签署令牌如何工作? (无效签名错误)

PHP中的Auth0 JWT令牌验证