zhangzengfei
2021-11-08 cd769ea498c08d5742b444fe6451b4c22899a317
licence.go
@@ -2,15 +2,18 @@
import (
   "encoding/json"
   "fmt"
   "io/ioutil"
   "os"
   "time"
   "errors"
)
/*
   1.0.0 采集机器码, 授权日期 然后 AES 加密, 生成Licence, 秘钥会暴露给客户端
   1.0.1 修改为RSA 非对称加密, 公钥开放. 加密内容为{注册码{机器码+公司+邮箱+手机}+过期时间+授权时间}
   1.0.2 修改Licence文件内容最终为AES加密后的内容, 然后再由公钥解密. 上个版本的bug, 仅使用非对称加密, 用户可以替换公钥
   1.0.3 授权文件添加通道数量, 增加读取通道数量接口
*/
type RegisterCode struct {
   MachineCode string
@@ -22,6 +25,7 @@
type Licence struct {
   RegCode   RegisterCode
   Channel   int64
   Expires   int64
   Timestamp int64
}
@@ -32,7 +36,7 @@
   ValidationErrorExpired                            // Signature expired
   ValidationErrorMalformed
   Version = "1.0.2"
   Version = "1.0.3"
   aesKey  = "www.aiotlink.com"
)
@@ -50,7 +54,7 @@
   return AESDecodeStr(regCode, aesKey)
}
func GenerateLicence(regCode, timeOut string, privateKey []byte) (string, error) {
func GenerateLicence(regCode, timeOut, privateKeyPath string, channel int64) (string, error) {
   timeLayout := "2006-01-02 15:04:05"  //转化所需模板
   loc, _ := time.LoadLocation("Local") //获取时区
   tmp, _ := time.ParseInLocation(timeLayout, timeOut, loc)
@@ -63,9 +67,22 @@
      return "", err
   }
   licence := Licence{registerCode, exp, now}
   licence := Licence{registerCode, channel,exp, now}
   json, err := json.Marshal(licence)
   if err != nil {
      return "", err
   }
   fd, err := os.Open(privateKeyPath)
   if err != nil {
      fmt.Println(err)
      return "", err
   }
   defer fd.Close()
   privateKey, err := ioutil.ReadAll(fd)
   if err != nil {
      fmt.Println(err)
      return "", err
   }
@@ -82,31 +99,31 @@
   return AESEncodeStr(licenceHex, aesKey), nil
}
func DecryptLicence(licencePath, publicKeyPath string) ([]byte, error) {
   var publicKey, licenceCode []byte
   var fdLic, fdPub *os.File
   var err error
func DecryptLicenceFile(licencePath, publicKeyPath string) ([]byte, error) {
   // 读取Licence File
   fdLic, err = os.Open(licencePath)
   fdLic, err := os.Open(licencePath)
   if err != nil {
      return nil, err
   }
   defer fdLic.Close()
   licenceCode, err = ioutil.ReadAll(fdLic)
   licenceCode, err := ioutil.ReadAll(fdLic)
   if err != nil {
      return nil, err
   }
   return DecryptLicence(string(licenceCode), publicKeyPath)
}
func DecryptLicence(licenceCode, publicKeyPath string) ([]byte, error) {
   // 读取公钥
   fdPub, err = os.Open(publicKeyPath)
   fdPub, err := os.Open(publicKeyPath)
   if err != nil {
      return nil, err
   }
   defer fdPub.Close()
   publicKey, err = ioutil.ReadAll(fdPub)
   publicKey, err := ioutil.ReadAll(fdPub)
   if err != nil {
      return nil, err
   }
@@ -116,25 +133,65 @@
      return nil, err
   }
   licenceHex := AESDecodeStr(string(licenceCode), aesKey)
   licenceHex := AESDecodeStr(licenceCode, aesKey)
   return RSA.PubKeyDECRYPT(licenceHex)
}
func VerifyLicence(licencePath, publicKeyPath string) uint32 {
   licenceText, err := DecryptLicence(licencePath, publicKeyPath)
func VerifyLicenceFile(licencePath, publicKeyPath string) uint32 {
   licenceText, err := DecryptLicenceFile(licencePath, publicKeyPath)
   if err != nil {
      return ValidationErrorDecrypt
   }
   return _verifyLicence(licenceText)
}
func VerifyLicence(licenceCode, publicKeyPath string) uint32 {
   licenceText, err := DecryptLicence(licenceCode, publicKeyPath)
   if err != nil {
      return ValidationErrorDecrypt
   }
   return _verifyLicence(licenceText)
}
func ReadGrantChannels(licencePath, publicKeyPath string) (int64, error) {
   licenceText, err := DecryptLicenceFile(licencePath, publicKeyPath)
   if err != nil {
      return 0 ,err
   }
   var licence Licence
   if err := json.Unmarshal(licenceText, &licence); err != nil {
      return 0, err
   }
   if _verifyLicence(licenceText) != 0 {
      return 0, errors.New("Invalid licence.")
   }
   return licence.Channel, nil
}
func _verifyLicence(licenceText []byte) uint32 {
   var licence Licence
   var now = time.Now().Unix()
   if err := json.Unmarshal(licenceText, &licence); err != nil {
      return ValidationErrorMalformed
   }
   // 判断是否可以试用
   if licence.RegCode.MachineCode == "FFFFFFFF" {
      osInstallTime := GetOSInstallationDate()
      if now - osInstallTime > 60 * 60 * 24 * 30 {
         return ValidationErrorExpired
      }
      return 0
   }
   // 判断过期
   now := time.Now().Unix()
   if now > licence.Expires {
      return ValidationErrorExpired
   }