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/rsa或crypto/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库。

