Golang中如何创建公钥/私钥JWK

Golang中如何创建公钥/私钥JWK 我一直在搜索,但似乎找不到任何关于创建JSON Web Key的提示。我找到了 jwk包 - github.com/lestrrat-go/jwx/jwk - pkg.go.dev 但在我的搜索中没有找到示例,还有 Go 如何生成 JSON Web Key (JWK) 但这个需要付费许可证。有没有人能给我指一个示例,希望可以使用Go库实现而不需要第三方库? 我对Go还比较陌生,所以还在摸索中。

谢谢


更多关于Golang中如何创建公钥/私钥JWK的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何创建公钥/私钥JWK的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中创建JWK(JSON Web Key)可以使用标准库crypto/rsacrypto/ecdsa生成密钥,然后手动构建JWK结构。以下是两种常见密钥类型的示例:

1. 生成RSA密钥对并输出为JWK

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "math/big"
)

func main() {
    // 生成RSA私钥
    privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        panic(err)
    }

    // 构建私钥JWK
    jwkPrivate := map[string]interface{}{
        "kty": "RSA",
        "n":   base64.RawURLEncoding.EncodeToString(privateKey.N.Bytes()),
        "e":   base64.RawURLEncoding.EncodeToString(big.NewInt(int64(privateKey.E)).Bytes()),
        "d":   base64.RawURLEncoding.EncodeToString(privateKey.D.Bytes()),
        "p":   base64.RawURLEncoding.EncodeToString(privateKey.Primes[0].Bytes()),
        "q":   base64.RawURLEncoding.EncodeToString(privateKey.Primes[1].Bytes()),
        "dp":  base64.RawURLEncoding.EncodeToString(privateKey.Precomputed.Dp.Bytes()),
        "dq":  base64.RawURLEncoding.EncodeToString(privateKey.Precomputed.Dq.Bytes()),
        "qi":  base64.RawURLEncoding.EncodeToString(privateKey.Precomputed.Qinv.Bytes()),
    }

    // 构建公钥JWK
    jwkPublic := map[string]interface{}{
        "kty": "RSA",
        "n":   jwkPrivate["n"],
        "e":   jwkPrivate["e"],
    }

    // 输出JSON
    privateJSON, _ := json.MarshalIndent(jwkPrivate, "", "  ")
    publicJSON, _ := json.MarshalIndent(jwkPublic, "", "  ")
    
    fmt.Println("私钥JWK:")
    fmt.Println(string(privateJSON))
    fmt.Println("\n公钥JWK:")
    fmt.Println(string(publicJSON))
}

2. 生成EC P-256密钥对并输出为JWK

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "math/big"
)

func main() {
    // 生成EC私钥
    privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    if err != nil {
        panic(err)
    }

    // 坐标转字节切片
    xBytes := privateKey.X.Bytes()
    yBytes := privateKey.Y.Bytes()
    dBytes := privateKey.D.Bytes()

    // 填充到正确长度
    keySize := (privateKey.Curve.Params().BitSize + 7) / 8
    paddedX := make([]byte, keySize)
    paddedY := make([]byte, keySize)
    paddedD := make([]byte, keySize)
    
    copy(paddedX[keySize-len(xBytes):], xBytes)
    copy(paddedY[keySize-len(yBytes):], yBytes)
    copy(paddedD[keySize-len(dBytes):], dBytes)

    // 构建私钥JWK
    jwkPrivate := map[string]interface{}{
        "kty": "EC",
        "crv": "P-256",
        "x":   base64.RawURLEncoding.EncodeToString(paddedX),
        "y":   base64.RawURLEncoding.EncodeToString(paddedY),
        "d":   base64.RawURLEncoding.EncodeToString(paddedD),
    }

    // 构建公钥JWK
    jwkPublic := map[string]interface{}{
        "kty": "EC",
        "crv": "P-256",
        "x":   jwkPrivate["x"],
        "y":   jwkPrivate["y"],
    }

    // 输出JSON
    privateJSON, _ := json.MarshalIndent(jwkPrivate, "", "  ")
    publicJSON, _ := json.MarshalIndent(jwkPublic, "", "  ")
    
    fmt.Println("私钥JWK:")
    fmt.Println(string(privateJSON))
    fmt.Println("\n公钥JWK:")
    fmt.Println(string(publicJSON))
}

3. 使用github.com/lestrrat-go/jwx/jwk库的示例

如果你决定使用第三方库,这里有个简单示例:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "github.com/lestrrat-go/jwx/jwk"
)

func main() {
    // 生成RSA密钥
    key, err := jwk.NewRSAKey()
    if err != nil {
        panic(err)
    }

    // 设置密钥ID
    _ = key.Set(jwk.KeyIDKey, "my-key-id")

    // 输出公钥JWK
    pubKey, err := jwk.PublicKeyOf(key)
    if err != nil {
        panic(err)
    }

    buf, _ := json.MarshalIndent(pubKey, "", "  ")
    fmt.Println(string(buf))
}

这些示例展示了如何在不依赖付费库的情况下创建JWK。第一个示例完全使用标准库,第二个示例使用了流行的开源jwx库。

回到顶部