将 JWK json 转换为公钥 golang (lestrrat-go)

2023-12-31

我使用 JWKS 格式从身份验证服务提供公钥,该公钥可用于验证来自该身份验证服务的令牌。但是,要执行验证,我需要从 JWK 重建公钥。我该如何转换它?

type JWKeys struct {
    Keys []JWKey `json:"keys"`
}

type JWKey struct {
    Kty string `json:"kty"`
    Use string `json:"use,omitempty"`
    Kid string `json:"kid,omitempty"`
    Alg string `json:"alg,omitempty"`

    Crv string `json:"crv,omitempty"`
    X   string `json:"x,omitempty"`
    Y   string `json:"y,omitempty"`
    D   string `json:"d,omitempty"`
    N   string `json:"n,omitempty"`
    E   string `json:"e,omitempty"`
    K   string `json:"k,omitempty"`
}

var PublicKey *rsa.PublicKey

func SetUpExternalAuth() {
    res, err := http.Get("my_url")

    if err != nil {
        log.Fatal("Can't retrieve the key for authentication")
    }

    bodyBytes, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
    }

    var keys JWKeys

    json.Unmarshal(bodyBytes, &keys)

    //CONVERT JWK TO *rsa.PUBLICKEY???
}

UPDATE

我尝试使用 github.com/lestrrat-go/jwx/jwk 库解析 JWK,但是我找不到如何继续:

set,err := jwk.Parse(bodyBytes)

key,err2 := set.Get(0)

//HOW TO CONVERT KEY INTO A *rsa.PublicKey?

最后我手动转换了它:

if singleJWK.Kty != "RSA" {
            log.Fatal("invalid key type:", singleJWK.Kty)
        }

        // decode the base64 bytes for n
        nb, err := base64.RawURLEncoding.DecodeString(singleJWK.N)
        if err != nil {
            log.Fatal(err)
        }

        e := 0
        // The default exponent is usually 65537, so just compare the
        // base64 for [1,0,1] or [0,1,0,1]
        if singleJWK.E == "AQAB" || singleJWK.E == "AAEAAQ" {
            e = 65537
        } else {
            // need to decode "e" as a big-endian int
            log.Fatal("need to deocde e:", singleJWK.E)
        }

        PublicKey = &rsa.PublicKey{
            N: new(big.Int).SetBytes(nb),
            E: e,
        }


了解您有一个解决方案,但当您尝试使用时github.com/lestrrat-go/jwx/jwk这是该包的一种方法(几乎是example https://github.com/lestrrat-go/jwx/blob/main/examples/jwk_example_test.go#L18):

package main

import (
    "context"
    "crypto/rsa"
    "fmt"
    "log"

    "github.com/lestrrat-go/jwx/jwk"
)

func main() {
    // Example jwk from https://www.googleapis.com/oauth2/v3/certs (but with only one cert for simplicity)
    jwkJSON := `{
  "keys": [ 
    {
      "kty": "RSA",
      "n": "o76AudS2rsCvlz_3D47sFkpuz3NJxgLbXr1cHdmbo9xOMttPMJI97f0rHiSl9stltMi87KIOEEVQWUgMLaWQNaIZThgI1seWDAGRw59AO5sctgM1wPVZYt40fj2Qw4KT7m4RLMsZV1M5NYyXSd1lAAywM4FT25N0RLhkm3u8Hehw2Szj_2lm-rmcbDXzvjeXkodOUszFiOqzqBIS0Bv3c2zj2sytnozaG7aXa14OiUMSwJb4gmBC7I0BjPv5T85CH88VOcFDV51sO9zPJaBQnNBRUWNLh1vQUbkmspIANTzj2sN62cTSoxRhSdnjZQ9E_jraKYEW5oizE9Dtow4EvQ",
      "use": "sig",
      "alg": "RS256",
      "e": "AQAB",
      "kid": "6a8ba5652a7044121d4fedac8f14d14c54e4895b"
    }
  ]
}
`

    set, err := jwk.Parse([]byte(jwkJSON))
    if err != nil {
        panic(err)
    }
    fmt.Println(set)
    for it := set.Iterate(context.Background()); it.Next(context.Background()); {
        pair := it.Pair()
        key := pair.Value.(jwk.Key)

        var rawkey interface{} // This is the raw key, like *rsa.PrivateKey or *ecdsa.PrivateKey
        if err := key.Raw(&rawkey); err != nil {
            log.Printf("failed to create public key: %s", err)
            return
        }

        // We know this is an RSA Key so...
        rsa, ok := rawkey.(*rsa.PublicKey)
        if !ok {
            panic(fmt.Sprintf("expected ras key, got %T", rawkey))
        }
        // As this is a demo just dump the key to the console
        fmt.Println(rsa)
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 JWK json 转换为公钥 golang (lestrrat-go) 的相关文章

随机推荐

  • Svg 在 Firefox 和 Edge 上显示不同

    我在处理中间有数字的 svg 图像时遇到一些问题 使用 Chrome 和其他浏览器时显示正确 但在 Firefox 和 Edge 中数字位置错误 Link https i stack imgur com VkvEJ png 这是我的代码 m
  • 拒绝应用样式,因为其 MIME 类型('application/json')不受支持

    我想使用fullcalendar库 使用gulp和yarn这是生成的链接标签 但我在控制台中收到此错误 拒绝应用样式 http localhost bower components fullcalendar dist fullcalenda
  • F#:没有 UI(如 WPF)吗?

    我最近在 F 上看到了一些视频 看来它主要用于服务或仅用于类 我在 VS2010 Beta 中没有看到 F WPF 应用程序 F 实际上有一些非常好的构造用于创建事件驱动的 UI 应用程序 例如头等舱活动 http blogs msdn c
  • 小黄瓜场景应该始终有“何时”步骤吗?

    在 Gherkin 中定义场景时 有时 Given 和 When 步骤之间没有明显区别 即用户没有与系统进行主动交互 验证的目的是验证系统在某些情况下应如何显示 考虑以下 Scenario Show current balance Give
  • ClickOnce 应用程序不接受命令行参数

    我有一个采用命令行参数的 VB NET 应用程序 如果我关闭 Visual Studio 的 ClickOnce 安全设置 调试时它可以正常工作 当我尝试通过 ClickOnce 在计算机上安装应用程序并尝试使用参数运行它时 会出现此问题
  • 为什么装饰器是一种结构性设计模式而不是行为性设计模式?

    我认为自己拥有 GoF 设计模式的中级知识 然而 当我将这些模式分类为结构模式和行为模式时 我感到很困惑 我对创造模式没有任何困惑 来自维基百科 装饰器模式 在面向对象编程中 装饰器模式是一种允许behavior静态或动态地添加到单个对象
  • Haskell有foldlM'吗?

    如何严格折叠 monad Data Foldable http www haskell org ghc docs 6 12 2 html libraries base 4 2 0 1 Data Foldable html有严格的foldl
  • REBOL 中的 If...else if...else

    我注意到 REBOL 没有内置if elsif else语法 就像这样 theVar 60 This won t work if theVar gt 60 print Greater than 60 elsif theVar 3 print
  • 如何仅使用 CSS 制作网格(如方格纸网格)?

    如何仅使用 CSS 制作网格 如方格纸网格 我只想仅使用 CSS 制作一张虚拟网格纸 要制作网格 您可以使用 CSS 渐变 它适用于所有现代浏览器 参见卡尼乌斯 http caniuse com search linear gradient
  • 如何调用自定义函数作为 jQuery 函数链的一部分

    这似乎是一件很简单的事情 但我找不到jQuery函数来处理这个问题 例如 div show sayHi function sayHi obj obj html hi sayHi 不是一个jQuery函数 因此不能在此上下文中调用它 你需要这
  • 不使用 Javascript 从 Google 地图获取路线和方向?

    因此 如果您正在编写一个应用程序 而不是网站 并且需要解析从一个位置到另一个位置的路线 那么如何在不使用 Javascript 的情况下从 Google 地图获取信息呢 我想知道 Google 地图上是否有任何一组特殊的 URL 或 API
  • 找不到盒子“laravel/homestead”

    我已经下载了laravel homestead手动装箱here https atlas hashicorp com laravel boxes homestead 我成功添加了盒子 vagrant box add file path to
  • 在 Bash 中,有没有办法在双引号中将变量展开两次?

    为了调试我的脚本 我想在每个输出的开头添加内部变量 FUNCNAME 和 LINENO 这样我就知道输出发生在哪个函数和行号上 foo local bar something echo FUNCNAME LINENO I just set
  • Pyinstaller 设置图标不改变

    当我使用命令时 pyinstaller exe icon test ico F noconsole test py 所有图标均不会更改为 test ico 一些图标保留为 pyinstaller 的默认图标 Why 所有图标均更改为 视窗
  • 使用字母间距填充div

    我遇到的问题是填写div与文本使用letter spacing 主要问题是我不知道宽度div 首先我想使用 text align justify 但从那以后我一直在黑暗中奔跑 不知道如何解决这个问题 我猜想一些脚本魔法可能会解决这个问题 一
  • 冲突的类型和先前的 x 声明在这里......什么?

    当我有时间的时候 我已经自学了几个月的 C 语言 但我遇到了一个我不知道如何解决的问题 具体来说 当我尝试使用 gcc 编译它时 我得到 geometry c 8 error conflicting types for trapezoid
  • 来自带有时区和夏令时的字符串的 Qt QDateTime

    我正在从字符串插入时间 QDateTime time QDateTime fromString Wed Mar 26 22 37 40 2019 GMT 08 qDebug lt
  • 从通知区域发出的卡通语音气泡叫什么?如何创建一个?

    谁能告诉我以下弹出窗口的名称是什么 如何为我的应用程序创建这样的弹出窗口 To be more specific this is indeed called a Notification http msdn microsoft com en
  • Clojure中如何加载程序资源

    如何在 Clojure 程序中加载图标 字符串 图形元素 脚本等程序资源 我使用的项目布局类似于许多 Java 项目中的布局 其中有一个 资源 目录挂在 源 目录下 jar 文件是从源代码创建的并包含资源 但我似乎无法像在 Java 中那样
  • 将 JWK json 转换为公钥 golang (lestrrat-go)

    我使用 JWKS 格式从身份验证服务提供公钥 该公钥可用于验证来自该身份验证服务的令牌 但是 要执行验证 我需要从 JWK 重建公钥 我该如何转换它 type JWKeys struct Keys JWKey json keys type