如何使用RSA实现NodeJS与Golang间JWT互签互验及公钥格式适配
Go与NodeJS RSA公钥互操作(适配jsonwebtoken库)
核心原理
跨语言的RSA密钥通用交互格式为PEM编码的PKIX格式公钥,NodeJS的jsonwebtoken库原生支持该格式,不需要额外转换。
1. Go侧导出RSA公钥为兼容格式
你当前代码报错的原因是privateIdentificationKey.PublicKey是rsa.PublicKey结构体类型,不能直接当做字符串传入identify函数,需要先序列化为PEM格式字符串。
公钥导出工具函数
import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" ) // 导出RSA公钥为PEM格式字符串 func ExportRSAPublicKeyToPEM(pub *rsa.PublicKey) (string, error) { pubASN1, err := x509.MarshalPKIXPublicKey(pub) if err != nil { return "", err } pubBlock := &pem.Block{ Type: "PUBLIC KEY", Bytes: pubASN1, } return string(pem.EncodeToMemory(pubBlock)), nil }
修正后的调用代码
// 生成私钥 var privateIdentificationKey = generatePrivateKey() // 导出公钥为字符串 pubKeyStr, err := ExportRSAPublicKeyToPEM(&privateIdentificationKey.PublicKey) if err != nil { fmt.Println("公钥导出失败:", err) return } // 调用identify函数 identify(id.String(), pubKeyStr)
2. Go侧解析NodeJS提供的公钥
NodeJS侧导出公钥时输出PEM格式即可,Go侧使用以下工具函数解析为rsa.PublicKey结构体,即可用于JWT验签:
// 从PEM字符串解析RSA公钥 func ParseRSAPublicKeyFromPEM(pubPemStr string) (*rsa.PublicKey, error) { block, _ := pem.Decode([]byte(pubPemStr)) if block == nil || block.Type != "PUBLIC KEY" { return nil, errors.New("无效的公钥PEM格式") } pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } pub, ok := pubInterface.(*rsa.PublicKey) if !ok { return nil, errors.New("公钥不是RSA类型") } return pub, nil }
3. NodeJS侧适配说明
- 使用
jsonwebtoken库验签Go生成的JWT时,直接把Go侧导出的PEM公钥字符串传入verify方法的公钥参数即可 - NodeJS侧导出公钥给Go使用时,使用crypto模块导出为PEM格式即可,示例:
const crypto = require('crypto'); // 生成密钥对后导出公钥 const publicKeyPem = keyPair.publicKey.export({ type: 'spki', format: 'pem' });
内容的提问来源于stack exchange,提问作者ZARKONES
相关产品推荐
相关产品推荐

