This commit is contained in:
parent
7adc7499ff
commit
0d75f1c58c
|
|
@ -1,14 +1,15 @@
|
||||||
package license
|
package license
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -30,15 +31,14 @@ func SignPayload(payload []byte) (string, error) {
|
||||||
return base64.StdEncoding.EncodeToString(sig), nil
|
return base64.StdEncoding.EncodeToString(sig), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifySignature(pubKey *ecdsa.PublicKey, payload []byte, signature string) bool {
|
func VerifySignature(pub *rsa.PublicKey, message []byte, signatureBase64 string) bool {
|
||||||
sigBytes, _ := base64.StdEncoding.DecodeString(signature)
|
signature, err := base64.StdEncoding.DecodeString(signatureBase64)
|
||||||
r := big.Int{}
|
if err != nil {
|
||||||
s := big.Int{}
|
return false
|
||||||
r.SetBytes(sigBytes[:len(sigBytes)/2])
|
}
|
||||||
s.SetBytes(sigBytes[len(sigBytes)/2:])
|
hashed := sha256.Sum256(message)
|
||||||
|
err = rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed[:], signature)
|
||||||
hash := sha256.Sum256(payload)
|
return err == nil
|
||||||
return ecdsa.Verify(pubKey, hash[:], &r, &s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExportPublicKeyPEM() string {
|
func ExportPublicKeyPEM() string {
|
||||||
|
|
|
||||||
|
|
@ -62,17 +62,28 @@ func ValidateLicenseHandler(db storage.Database) fiber.Handler {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload)
|
payloadBytes, err := base64.StdEncoding.DecodeString(lf.Payload)
|
||||||
var req LicenseRequest
|
if err != nil {
|
||||||
json.Unmarshal(payloadBytes, &req)
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid payload encoding")
|
||||||
|
|
||||||
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
|
||||||
return fiber.NewError(401, "Invalid license signature")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expiry, _ := time.Parse("2006-01-02", req.Expiry)
|
// 先验证签名是否真的是对 payloadBytes 签的
|
||||||
|
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
||||||
|
return fiber.NewError(fiber.StatusUnauthorized, "Invalid license signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证通过后再解析 payload 内容
|
||||||
|
var req LicenseRequest
|
||||||
|
if err := json.Unmarshal(payloadBytes, &req); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Malformed payload")
|
||||||
|
}
|
||||||
|
|
||||||
|
expiry, err := time.Parse("2006-01-02", req.Expiry)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid expiry date")
|
||||||
|
}
|
||||||
if time.Now().After(expiry) {
|
if time.Now().After(expiry) {
|
||||||
return fiber.NewError(403, "License expired")
|
return fiber.NewError(fiber.StatusForbidden, "License expired")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(fiber.Map{"valid": true, "features": req.Features})
|
return c.JSON(fiber.Map{"valid": true, "features": req.Features})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue