package licence
|
|
import (
|
"encoding/json"
|
"fmt"
|
"io/ioutil"
|
"os"
|
"time"
|
)
|
|
/*
|
1.0.0 采集机器码, 授权日期 然后 AES 加密, 生成Licence, 秘钥会暴露给客户端
|
1.0.1 修改为RSA 非对称加密, 公钥开放. 加密内容为{注册码{机器码+公司+邮箱+手机}+过期时间+授权时间}
|
1.0.2 修改Licence文件内容最终为AES加密后的内容, 然后再由公钥解密. 上个版本的bug, 仅使用非对称加密, 用户可以替换公钥
|
*/
|
type RegisterCode struct {
|
MachineCode string
|
Company string
|
Email string
|
Phone string
|
Version string
|
}
|
|
type Licence struct {
|
RegCode RegisterCode
|
Expires int64
|
Timestamp int64
|
}
|
|
const (
|
ValidationErrorDecrypt uint32 = iota + 1 // Licence is malformed
|
ValidationErrorUnverifiableHost // Host unauthorized
|
ValidationErrorExpired // Signature expired
|
ValidationErrorMalformed
|
|
Version = "1.0.3"
|
aesKey = "www.aiotlink.com"
|
)
|
|
func GetRegisterCode(company, email, phone string) string {
|
mCode := GetMachineCode()
|
|
regCode := RegisterCode{mCode, company, email, phone, Version}
|
|
json, _ := json.Marshal(regCode)
|
|
return AESEncodeStr(json, aesKey)
|
}
|
|
func DecryptRegisterCode(regCode string) []byte {
|
return AESDecodeStr(regCode, aesKey)
|
}
|
|
func GenerateLicence(regCode, timeOut, privateKeyPath string) (string, error) {
|
timeLayout := "2006-01-02 15:04:05" //转化所需模板
|
loc, _ := time.LoadLocation("Local") //获取时区
|
tmp, _ := time.ParseInLocation(timeLayout, timeOut, loc)
|
exp := tmp.Unix()
|
now := time.Now().Unix()
|
|
regCodeText := AESDecodeStr(regCode, aesKey)
|
var registerCode RegisterCode
|
if err := json.Unmarshal(regCodeText, ®isterCode); err != nil {
|
return "", err
|
}
|
|
licence := Licence{registerCode, 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
|
}
|
|
RSA := &RSASecurity{}
|
if err := RSA.SetPrivateKey(privateKey); err != nil {
|
return "", err
|
}
|
|
licenceHex, err := RSA.PriKeyENCTYPT(json)
|
if err != nil {
|
return "", err
|
}
|
|
return AESEncodeStr(licenceHex, aesKey), nil
|
}
|
|
func DecryptLicenceFile(licencePath, publicKeyPath string) ([]byte, error) {
|
// 读取Licence File
|
fdLic, err := os.Open(licencePath)
|
if err != nil {
|
return nil, err
|
}
|
defer fdLic.Close()
|
|
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)
|
if err != nil {
|
return nil, err
|
}
|
defer fdPub.Close()
|
|
publicKey, err := ioutil.ReadAll(fdPub)
|
if err != nil {
|
return nil, err
|
}
|
|
RSA := &RSASecurity{}
|
if err := RSA.SetPublicKey(publicKey); err != nil {
|
return nil, err
|
}
|
|
licenceHex := AESDecodeStr(licenceCode, aesKey)
|
|
return RSA.PubKeyDECRYPT(licenceHex)
|
}
|
|
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 _verifyLicence(licenceText []byte) uint32 {
|
var licence Licence
|
|
if err := json.Unmarshal(licenceText, &licence); err != nil {
|
return ValidationErrorMalformed
|
}
|
|
// 判断过期
|
now := time.Now().Unix()
|
if now > licence.Expires {
|
return ValidationErrorExpired
|
}
|
|
// 判断机器码
|
mCode := GetMachineCode()
|
if licence.RegCode.MachineCode != mCode {
|
return ValidationErrorUnverifiableHost
|
}
|
|
return 0
|
}
|