|
@@ -1,22 +1,27 @@
|
|
|
package api
|
|
|
|
|
|
import (
|
|
|
- "box-cost/conf"
|
|
|
+ "box-cost/db/model"
|
|
|
"box-cost/db/repo"
|
|
|
- "box-cost/log"
|
|
|
- "crypto/hmac"
|
|
|
+ "crypto"
|
|
|
+ "crypto/rand"
|
|
|
+ "crypto/rsa"
|
|
|
"crypto/sha256"
|
|
|
+ "crypto/x509"
|
|
|
+ "encoding/base64"
|
|
|
+ "encoding/json"
|
|
|
+ "encoding/pem"
|
|
|
+ "errors"
|
|
|
"fmt"
|
|
|
- "net/http"
|
|
|
+ "io/ioutil"
|
|
|
+ "os"
|
|
|
"time"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
- "github.com/shirou/gopsutil/net"
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
)
|
|
|
|
|
|
func Mac(r *GinRouter) {
|
|
|
- r.GET("/mac/info", MacInfo)
|
|
|
r.POST("/get/code", GetCode)
|
|
|
}
|
|
|
|
|
@@ -29,96 +34,189 @@ type DeviceInfo struct {
|
|
|
|
|
|
const SECRET_KEY = "DFDFEXVEG"
|
|
|
|
|
|
-func MacInfo(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
- fmt.Println(conf.AppConfig.Name)
|
|
|
- interfaces, err := net.Interfaces()
|
|
|
+func GetCode(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+
|
|
|
+ form := model.RegCodeReq{}
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
return nil, err
|
|
|
}
|
|
|
- macAddr := getRealMacAddr(interfaces)
|
|
|
- deviceInfo := &DeviceInfo{
|
|
|
- DeviceId: UtilMd5(macAddr),
|
|
|
- AppName: "Toolchain",
|
|
|
- AppVersion: "v1.0.0",
|
|
|
- CreateTime: time.Now(),
|
|
|
+ fmt.Println(form)
|
|
|
+
|
|
|
+ return nil, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func CreatePrivateKey() error {
|
|
|
+ privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // 将私钥编码为PEM格式
|
|
|
+ privateKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
|
+ Type: "RSA PRIVATE KEY",
|
|
|
+ Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
|
|
+ })
|
|
|
+ // 将私钥保存到文件中
|
|
|
+ err = ioutil.WriteFile("certs/private_key.pem", privateKeyPEM, 0600)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return err
|
|
|
}
|
|
|
+ return nil
|
|
|
+}
|
|
|
|
|
|
- return deviceInfo, nil
|
|
|
+func CreatePublicKey(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // privateKeyFile, err := os.Open(fileName)
|
|
|
+ privateKeyFile, err := os.Open("certs/private_key.pem")
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ defer privateKeyFile.Close()
|
|
|
+ privateKeyPEM, err := ioutil.ReadAll(privateKeyFile)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ privateKeyBlock, _ := pem.Decode(privateKeyPEM)
|
|
|
+ privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ // 根据私钥生成公钥
|
|
|
+ publicKey1 := privateKey.PublicKey
|
|
|
+ // 根据index的 不同生成不同的publickey
|
|
|
+ index, err := repo.RepoCountDoc(apictx.CreateRepoCtx(), "reg-code", repo.Map{"status": 1})
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ publicKey := rsa.PublicKey{
|
|
|
+ N: publicKey1.N,
|
|
|
+ E: 65537 + int(index),
|
|
|
+ }
|
|
|
+ publicKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
|
+ Type: "RSA PUBLIC KEY",
|
|
|
+ Bytes: x509.MarshalPKCS1PublicKey(&publicKey),
|
|
|
+ })
|
|
|
+
|
|
|
+ // 将公钥保存到文件中
|
|
|
+ err = ioutil.WriteFile("public_key.pem", publicKeyPEM, 0644)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return true, nil
|
|
|
}
|
|
|
|
|
|
-func GetCode(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
- deviceId := c.Query("deviceId")
|
|
|
- if len(deviceId) < 1 {
|
|
|
- fmt.Println("deviceId 为空")
|
|
|
- c.String(http.StatusOK, "err")
|
|
|
- return nil, nil
|
|
|
- }
|
|
|
- key := []byte(SECRET_KEY)
|
|
|
- message := []byte(deviceId) // 待签名的消息
|
|
|
-
|
|
|
- // 创建一个 HMAC-SHA256 实例
|
|
|
- h := hmac.New(sha256.New, key)
|
|
|
-
|
|
|
- // 写入消息
|
|
|
- h.Write(message)
|
|
|
-
|
|
|
- // 计算签名
|
|
|
- signature := h.Sum(nil)
|
|
|
- fmt.Printf("%x\n", signature)
|
|
|
- // fmt.Println(len("86068c837d554c8aba4f997b51be6bc209b68cdad7c5a4a0adccbfc289adf4a2"))
|
|
|
- // fmt.Println(len("63e208dc7452ab74932b9e37"))
|
|
|
- // fmt.Println(len(UtilMd5(mac)))
|
|
|
- appName := c.Query("appName")
|
|
|
- appVersion := c.Query("appVersion")
|
|
|
- // create_time := c.Query("createTime")
|
|
|
-
|
|
|
- // deviceId设置唯一key
|
|
|
- type RegCode struct {
|
|
|
- Id primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
|
|
|
- AppName string `bson:"appName,omitempty" json:"appName"`
|
|
|
- AppVersion string `bson:"appVersion,omitempty" json:"appVersion"`
|
|
|
- DeviceId string `bson:"deviceId,omitempty" json:"deviceId"`
|
|
|
- Key string `bson:"key,omitempty" json:"key"`
|
|
|
- Code string `bson:"code,omitempty" json:"code"`
|
|
|
- CreateTime time.Time `bson:"createTime,omitempty" json:"createTime"`
|
|
|
- UpdateTIme time.Time `bson:"updateTIme,omitempty" json:"updateTIme"`
|
|
|
- ExpireTime time.Time `bson:"expireTime,omitempty" json:"expireTime"`
|
|
|
- Status int `bson:"status,omitempty" json:"status"`
|
|
|
- }
|
|
|
- _, err := repo.RepoAddDoc(apictx.CreateRepoCtx(), "reg-code", &RegCode{
|
|
|
-
|
|
|
- AppName: appName,
|
|
|
- AppVersion: appVersion,
|
|
|
- DeviceId: deviceId,
|
|
|
- Key: SECRET_KEY,
|
|
|
- Code: fmt.Sprintf("%x", signature),
|
|
|
+// 生成激活码
|
|
|
+func CreateActiveCode(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 根据注册码生成激活码
|
|
|
+ // 解析注册码
|
|
|
+ type RegCodeReq struct {
|
|
|
+ Cipher string
|
|
|
+ }
|
|
|
+ form := RegCodeReq{}
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if len(form.Cipher) < 1 {
|
|
|
+ return nil, errors.New("注册码错误")
|
|
|
+ }
|
|
|
+
|
|
|
+ privateFile, err := os.Open("private_key.pem")
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+ defer privateFile.Close()
|
|
|
+ privateKeyPEM, err := ioutil.ReadAll(privateFile)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return false, errors.New("decode err")
|
|
|
+ }
|
|
|
+ privateKeyBlock, _ := pem.Decode(privateKeyPEM)
|
|
|
+ if privateKeyBlock == nil {
|
|
|
+ return false, errors.New("decode err")
|
|
|
+ }
|
|
|
+ privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
|
|
|
+ if err != nil {
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ decrypted, err := rsa.DecryptOAEP(
|
|
|
+ sha256.New(),
|
|
|
+ rand.Reader,
|
|
|
+ privateKey,
|
|
|
+ []byte(form.Cipher),
|
|
|
+ []byte(""),
|
|
|
+ )
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ decoded, err := base64.StdEncoding.DecodeString(string(decrypted))
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ regCodeReq := model.RegCodeReq{}
|
|
|
+ err = json.Unmarshal(decoded, ®CodeReq)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ fmt.Println(regCodeReq)
|
|
|
+ // 数据库操作
|
|
|
+ _id, err := repo.RepoAddDoc(apictx.CreateRepoCtx(), "reg-code", &model.RegCode{
|
|
|
+ UserId: apictx.User.Parent,
|
|
|
+ AppId: regCodeReq.AppId,
|
|
|
+ AppName: regCodeReq.AppName,
|
|
|
+ AppVersion: regCodeReq.AppVersion,
|
|
|
+ DeviceId: regCodeReq.DeviceId,
|
|
|
+ // RegCode: form.Code,
|
|
|
+ // ActiveCode
|
|
|
+ IsPerm: regCodeReq.IsPerm,
|
|
|
CreateTime: time.Now(),
|
|
|
UpdateTIme: time.Now(),
|
|
|
- ExpireTime: time.Now().AddDate(0, 0, 3),
|
|
|
+ ExpireTime: regCodeReq.ExpireTime,
|
|
|
Status: 1,
|
|
|
})
|
|
|
+
|
|
|
if err != nil {
|
|
|
- log.Error(err)
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- // 输出签名结果
|
|
|
- c.String(http.StatusOK, fmt.Sprintf("%x", signature))
|
|
|
- return nil, nil
|
|
|
+ // 组装返回数据
|
|
|
+ id, _ := primitive.ObjectIDFromHex(_id)
|
|
|
|
|
|
-}
|
|
|
+ // Calculate hash of ciphertext
|
|
|
+ hash := sha256.Sum256([]byte(form.Cipher))
|
|
|
|
|
|
-// b0:6e:bf:c5:32:30
|
|
|
-func getRealMacAddr(netInterfaces []net.InterfaceStat) string {
|
|
|
- loindex := 0
|
|
|
- for _, netInterface := range netInterfaces {
|
|
|
- if netInterface.Name == "lo" {
|
|
|
- loindex = netInterface.Index
|
|
|
- break
|
|
|
- }
|
|
|
+ // Generate signature
|
|
|
+ signature, err := rsa.SignPKCS1v15(
|
|
|
+ rand.Reader,
|
|
|
+ privateKey,
|
|
|
+ crypto.SHA256,
|
|
|
+ hash[:],
|
|
|
+ )
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return nil, err
|
|
|
}
|
|
|
- if len(netInterfaces) < loindex+1 {
|
|
|
- return ""
|
|
|
+
|
|
|
+ resp := &model.RegCodeResp{
|
|
|
+ Id: id,
|
|
|
+ AppId: regCodeReq.AppId,
|
|
|
+ AppName: regCodeReq.AppName,
|
|
|
+ AppVersion: regCodeReq.AppVersion,
|
|
|
+ Signature: string(signature),
|
|
|
+ CipherText: form.Cipher,
|
|
|
}
|
|
|
- return netInterfaces[loindex].HardwareAddr
|
|
|
+
|
|
|
+ return resp, nil
|
|
|
}
|