✨Feat: jwt token加密算法由ES256更换为HS256
This commit is contained in:
@@ -1,15 +1,8 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"drive-linked/config"
|
||||
"drive-linked/pkg/utils"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/kataras/golog"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -18,71 +11,15 @@ type JwtClaims struct {
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
var ECDSAKey *ecdsa.PrivateKey
|
||||
|
||||
// 生成ES256密钥对,并保存在文件中
|
||||
func init() {
|
||||
// 密钥对存在时跳过
|
||||
//TODO:bug:会重复生成key
|
||||
if isExist := utils.FileExist("id_ecdsa") && utils.FileExist("id_ecdsa.pub"); isExist {
|
||||
return
|
||||
}
|
||||
|
||||
key, err := newES256Key()
|
||||
if err != nil {
|
||||
golog.Fatal("生成ES256密钥错误")
|
||||
}
|
||||
|
||||
// 写入至文件
|
||||
pubKeyBytes, err := utils.EncodePublicKey(&key.PublicKey)
|
||||
if err != nil {
|
||||
golog.Fatal(err)
|
||||
}
|
||||
priKeyBytes, err := utils.EncodePrivateKey(key)
|
||||
if err != nil {
|
||||
golog.Fatal(err)
|
||||
}
|
||||
|
||||
priKeyFile, err := os.OpenFile("id_ecdsa", os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
golog.Fatal(err)
|
||||
}
|
||||
pubKeyFile, err := os.OpenFile("id_ecdsa.pub", os.O_CREATE, 0655)
|
||||
if err != nil {
|
||||
golog.Fatal(err)
|
||||
}
|
||||
priKeyFile.Write(priKeyBytes)
|
||||
pubKeyFile.Write(pubKeyBytes)
|
||||
}
|
||||
|
||||
func newES256Key() (key *ecdsa.PrivateKey, err error) {
|
||||
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
return key, err
|
||||
}
|
||||
|
||||
func LoadKey() error {
|
||||
if ECDSAKey != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
priKeyBytes, err := ioutil.ReadFile(config.Cfg.Security.Jwt.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := utils.DecodePrivateKey(priKeyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ECDSAKey = key
|
||||
return nil
|
||||
}
|
||||
|
||||
//TODO:token解密验证
|
||||
func ValidateLogin(token string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewToken(auds ...string) (string, error) {
|
||||
if len(auds) == 0 {
|
||||
auds = []string{"nonAudience"}
|
||||
}
|
||||
// Create the claims
|
||||
claims := JwtClaims{
|
||||
"bar",
|
||||
@@ -93,12 +30,12 @@ func NewToken(auds ...string) (string, error) {
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: "drivelinked",
|
||||
Subject: "login",
|
||||
Audience: []string{"eigeen"},
|
||||
Audience: auds,
|
||||
},
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
|
||||
ss, err := token.SignedString(ECDSAKey)
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
ss, err := token.SignedString([]byte(config.Cfg.Security.Jwt.Secret))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@@ -7,10 +7,6 @@ import (
|
||||
|
||||
func TestNewToken(t *testing.T) {
|
||||
config.SetupConfig()
|
||||
err := LoadKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
token, err := NewToken("eigeen")
|
||||
if err != nil {
|
||||
|
@@ -1,84 +1,20 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"github.com/kataras/golog"
|
||||
)
|
||||
|
||||
func DecodePublicKey(encodedKey []byte) (*ecdsa.PublicKey, error) {
|
||||
block, _ := pem.Decode(encodedKey)
|
||||
if block == nil || block.Type != "PUBLIC KEY" {
|
||||
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
|
||||
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
// NewKey 生成Key
|
||||
func NewKey() string {
|
||||
length := 48
|
||||
// HS256的key,其实就是个随机字符串生成器
|
||||
key := make([]byte, length/2)
|
||||
_, err := rand.Read(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
golog.Fatal(err)
|
||||
}
|
||||
|
||||
ecdsaPub, ok := pub.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errors.New("marshal: data was not an ECDSA public key")
|
||||
}
|
||||
|
||||
return ecdsaPub, nil
|
||||
}
|
||||
|
||||
func EncodePublicKey(key *ecdsa.PublicKey) ([]byte, error) {
|
||||
derBytes, err := x509.MarshalPKIXPublicKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block := &pem.Block{
|
||||
Type: "PUBLIC KEY",
|
||||
Bytes: derBytes,
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(block), nil
|
||||
}
|
||||
|
||||
func DecodePrivateKey(encodedKey []byte) (*ecdsa.PrivateKey, error) {
|
||||
var skippedTypes []string
|
||||
var block *pem.Block
|
||||
|
||||
for {
|
||||
block, encodedKey = pem.Decode(encodedKey)
|
||||
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
|
||||
}
|
||||
|
||||
if block.Type == "EC PRIVATE KEY" {
|
||||
break
|
||||
} else {
|
||||
skippedTypes = append(skippedTypes, block.Type)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
privKey, err := x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return privKey, nil
|
||||
}
|
||||
|
||||
func EncodePrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
|
||||
derKey, err := x509.MarshalECPrivateKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyBlock := &pem.Block{
|
||||
Type: "EC PRIVATE KEY",
|
||||
Bytes: derKey,
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(keyBlock), nil
|
||||
return hex.EncodeToString(key)
|
||||
}
|
||||
|
@@ -1,32 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDecodePrivateKey(t *testing.T) {
|
||||
priKeyStr, err := ioutil.ReadFile("../../config/id_ecdsa")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key, err := DecodePrivateKey(priKeyStr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
t.Log(key)
|
||||
}
|
||||
|
||||
func TestDecodePublicKey(t *testing.T) {
|
||||
priKeyStr, err := ioutil.ReadFile("../../config/id_ecdsa.pub")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key, err := DecodePublicKey(priKeyStr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
t.Log(key)
|
||||
}
|
Reference in New Issue
Block a user