Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将JWK json转换为公钥golang(lestrrat go)_Go_Cryptography_Public Key_Pem_Jwk - Fatal编程技术网

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

将JWK json转换为公钥golang(lestrrat go),go,cryptography,public-key,pem,jwk,Go,Cryptography,Public Key,Pem,Jwk,我使用JWKS格式从身份验证服务提供公钥,该公钥可用于验证来自该身份验证服务的令牌。但是,要执行验证,我需要从JWK重新生成公钥。我如何转换它 type JWKeys struct { Keys []JWKey `json:"keys"` } type JWKey struct { Kty string `json:"kty"` Use string `json:"use,omitempty"` Kid

我使用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???
}
更新

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

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,
        }


我写了一个围棋包就是为了这个目的:

转换为
*rsa.PublicKey
在这个包中,JSON Web键(JWK)看起来像这样的Go结构。它同时支持ECDSA和RSA JWK

//JSONKey表示JWKS中的原始密钥。
类型JSONKey结构{
曲线字符串`json:“crv”`
指数字符串`json:“e”`
ID字符串`json:“kid”`
模数字符串`json:“n”`
X字符串`json:“X”`
Y字符串`json:“Y”`
预计算接口{}
}
将原始JSON消息解组到上述结构中后,此方法将其转换为
*rsa.PublicKey

package-keyfunc
进口(
“加密/rsa”
“编码/base64”
“fmt”
“数学/大”
)
常数(
//rs256表示由256位RSA算法生成的公钥。
rs256=“rs256”
//rs384表示由384位RSA算法生成的公钥。
rs384=“rs384”
//rs512表示由512位RSA算法生成的公钥。
rs512=“rs512”
//ps256表示由256位RSA算法生成的公钥。
ps256=“ps256”
//ps384表示由384位RSA算法生成的公钥。
ps384=“ps384”
//ps512表示由512位RSA算法生成的公钥。
ps512=“ps512”
)
//RSA解析JSONKey并将其转换为RSA公钥。
func(j*JSONKey)RSA()(公钥*RSA.publicKey,错误){
//检查是否已计算密钥。
如果j.预计算!=nil{
返回预计算的j.(*rsa.PublicKey),无
}
//确认所有需要的东西都存在。
如果j.指数=“”| | j.模数=“”{
返回nil,fmt.Errorf(“%w:rsa”,ErrMissingAssets)
}
//从Base64解码指数。
//
//根据RFC 7518,这是一个Base64 URL无符号整数。
// https://tools.ietf.org/html/rfc7518#section-6.3
变量指数[]字节
如果是指数,err=base64.RawURLEncoding.DecodeString(j.exponent);err!=nil{
返回零,错误
}
//从Base64解码模数。
var模数[]字节
如果是模数,则err=base64.RawURLEncoding.DecodeString(j.module);err!=nil{
返回零,错误
}
//创建RSA公钥。
公钥=&rsa.publicKey{}
//将指数转换为整数。
//
//根据RFC 7517,这些数字采用大端格式。
// https://tools.ietf.org/html/rfc7517#appendix-A.1
publicKey.E=int(大.NewInt(0).SetBytes(指数).Uint64())
//将模数转换为*big.Int。
publicKey.N=big.NewInt(0).SetBytes(模数)
//保留公钥,这样就不必每次都计算它。
j、 预计算=公钥
返回公钥,无
}
从JSON Web密钥集(JWKS)解析和验证JWT。 我制作了这个包,以便使用最流行的包更容易地解析和验证JWTs

使用您的示例URL,
my_URL
,下面是一个如何解析和验证JWTs的示例

主程序包
进口(
“日志”
“时间”
“github.com/dgrijalva/jwt go”
“github.com/MicahParks/keyfunc”
)
func main(){
//获取JWKS URL。
jwksURL:=“我的url”
//创建keyfunc选项。每小时刷新一次JWKS并记录错误。
刷新间隔:=时间。小时
选项:=keyfunc.options{
刷新间隔:&刷新间隔,
RefreshErrorHandler:func(错误错误){
log.Printf(“jwt.KeyFunc\n错误:%s”,err.error()
},
}
//从给定URL处的资源创建JWKS。
jwks,err:=keyfunc.Get(jwksURL,选项)
如果错误!=零{
log.Fatalf(“无法从给定URL的资源创建JWKS。\n错误:%s”,err.Error())
}
//获取要解析的JWT。
jwtB64:="Eyjhbgiijquzm4ncijmedf5udjzqnr4yxftmvnljkr2lyuktudzvdjvxbvxljtqxfin0.Eyjlheaioj2 mtu5 odysimlhdc6ntqnjmyiwjjjyyy2wf5udjzqnr4wjjjjjjjjjjjjjjzm2wjjjjjjjjjjjjjjd2f2vzzzbjjjjjljjjjjjjjjjjjjjjd0.jjjjjjjjjjjjjjjjd0.jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj2月2日,中国政府提出了一种新的研究方法,即在2月2日,在2月2日,2月2日,2月2日,2月2日,2月2日,2月2日,2月2日,2月2日,在2月2日,在2月2日,2月2日,2月2日,2月2日,2日,2月2日,2日,2日,2月2日,2号,2号,2号,2号文ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ4YMC中国政府ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZATWOVJZ-frga0KFl-nLce3OwncRXVCGmxoFzUsyu9TQFS2Mm_P0AMX1Y1MAX1JMLC3WFHHH3BOHHRQPZBTJSFS_f46nE1-HKJQZ1ERRAC2FMIVJJMG7ST702JRUUZRGG4DkVCMLJ4NEJUMCD1VZYBRGGFAIXNKWHTMS2CP9TOCWNU47TSG”
//解析JWT。
令牌,err:=jwt.Parse(jwtB64,jwks.KeyFunc)
如果错误!=零{
log.Fatalf(“未能分析JWT。\n错误:%s”,err.Error())
}
//检查令牌是否有效。
if!token.Valid{
log.Fatalf(“令牌无效。”)
}
Println(“令牌有效”)
}
我写了