package api import ( "box-cost/db/model" "box-cost/db/repo" "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/json" "encoding/pem" "errors" "fmt" "io/ioutil" "os" "time" "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/bson/primitive" ) func Mac(r *GinRouter) { r.POST("/get/code", GetCode) } type DeviceInfo struct { DeviceId string CreateTime time.Time AppName string AppVersion string } const SECRET_KEY = "DFDFEXVEG" 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 } 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 } 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 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: regCodeReq.ExpireTime, Status: 1, }) if err != nil { return nil, err } // 组装返回数据 id, _ := primitive.ObjectIDFromHex(_id) // Calculate hash of ciphertext hash := sha256.Sum256([]byte(form.Cipher)) // Generate signature signature, err := rsa.SignPKCS1v15( rand.Reader, privateKey, crypto.SHA256, hash[:], ) if err != nil { fmt.Println(err) return nil, err } resp := &model.RegCodeResp{ Id: id, AppId: regCodeReq.AppId, AppName: regCodeReq.AppName, AppVersion: regCodeReq.AppVersion, Signature: string(signature), CipherText: form.Cipher, } return resp, nil }