From f5f618ac09975c6100c27aa7f90c8460d9d35c8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81=E6=BC=8F=E6=B4=9E?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=8C=E6=88=90?= <>
Date: Sun, 13 Apr 2025 02:05:41 +0800
Subject: [PATCH] add user and rsa
---
.idea/workspace.xml | 21 ++-
main.go | 354 ++++++++++++++++++++++++++++++++++++++++----
models/User.go | 76 ++++++++++
mydb/initialize.go | 4 +-
privateKey.pem | 3 +
5 files changed, 423 insertions(+), 35 deletions(-)
create mode 100644 models/User.go
create mode 100644 privateKey.pem
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 007b1ae..d2923e4 100755
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,9 +5,9 @@
+
-
-
+
@@ -69,6 +69,14 @@
+
+
+
+
+
+
+
+
@@ -78,6 +86,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/main.go b/main.go
index 8a51446..aa4e58c 100755
--- a/main.go
+++ b/main.go
@@ -1,7 +1,14 @@
package main
import (
+ "bytes"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
"database/sql"
+ "encoding/base64"
+ "encoding/json"
+ "encoding/pem"
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
_ "github.com/go-sql-driver/mysql"
@@ -10,7 +17,9 @@ import (
_ "go_mqtt/models"
"go_mqtt/mydb"
_ "go_mqtt/mydb"
+ "io/ioutil"
"log"
+ "os"
"strings"
"time"
)
@@ -177,6 +186,207 @@ func dbTest() {
stmt.Exec(1)
}
+
+// GenRsaKey generates an PKCS#1 RSA keypair of the given bit size in PEM format.
+func GenRsaKey(bits int) (prvkey, pubkey []byte, err error) {
+ // Generates private key.
+ privateKey, err := rsa.GenerateKey(rand.Reader, bits)
+ if err != nil {
+ return
+ }
+ derStream := x509.MarshalPKCS1PrivateKey(privateKey)
+ block := &pem.Block{
+ Type: "RSA PRIVATE KEY",
+ Bytes: derStream,
+ }
+ prvkey = pem.EncodeToMemory(block)
+
+ // Generates public key from private key.
+ publicKey := &privateKey.PublicKey
+ derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
+ if err != nil {
+ return
+ }
+ block = &pem.Block{
+ Type: "RSA PUBLIC KEY",
+ Bytes: derPkix,
+ }
+ pubkey = pem.EncodeToMemory(block)
+ return
+}
+
+
+
+
+func parsePrivateKey(privateKeyFile string) (*rsa.PrivateKey, error) {
+ // 读取私钥文件
+ keyData, err := ioutil.ReadFile(privateKeyFile)
+ if err != nil {
+ return nil, err
+ }
+
+ // 解析PEM块
+ block, _ := pem.Decode(keyData)
+ if block == nil {
+ return nil, fmt.Errorf("private key error not block in file")
+ }
+
+ // 解析RSA私钥
+ privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+ if err != nil {
+ return nil, err
+ }
+ return privateKey, nil
+}
+
+//生成RSA私钥和公钥,保存到文件中
+func GenerateRSAKey(bits int) {
+ //GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
+ //Reader是一个全局、共享的密码用强随机数生成器
+ privateKey, err := rsa.GenerateKey(rand.Reader, bits)
+ if err != nil {
+ return
+ }
+ //保存私钥
+ //通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
+ // X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) // PKCS1 和 9 是不一致的
+ X509PrivateKey, err := x509.MarshalPKCS8PrivateKey(privateKey)
+ if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(0)
+ }
+ //使用pem格式对x509输出的内容进行编码
+ //创建文件保存私钥
+ privateFile, err := os.Create("private.pem")
+ if err != nil {
+ return
+ }
+
+ //构建一个pem.Block结构体对象
+ privateBlock := pem.Block{Type: "PRIVATE KEY", Bytes: X509PrivateKey}
+ //将数据保存到文件
+ pem.Encode(privateFile, &privateBlock)
+ //保存公钥
+ //获取公钥的数据
+ publicKey := privateKey.PublicKey
+ //X509对公钥编码
+ X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
+ if err != nil {
+ return
+ }
+ //pem格式编码
+ //创建用于保存公钥的文件
+ publicFile, err := os.Create("public.pem")
+ if err != nil {
+ return
+ }
+
+ //创建一个pem.Block结构体对象
+ publicBlock := pem.Block{Type: "Public Key", Bytes: X509PublicKey}
+ //保存到文件
+ pem.Encode(publicFile, &publicBlock)
+}
+
+// RSA_Decrypts RSA解密支持分段解密
+func RSA_Decrypts(cipherText []byte, path string) []byte {
+ //打开文件
+ var bytesDecrypt []byte
+ //file, err := os.Open(path)
+ //if err != nil {
+ // fmt.Println(err)
+ //}
+ //
+ ////获取文件内容
+ //info, _ := file.Stat()
+ //buf := make([]byte, info.Size())
+ //file.Read(buf)
+
+ // 读取私钥文件
+ keyData, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil
+ }
+
+ //pem解码
+ block, _ := pem.Decode(keyData)
+ //X509解码
+ privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
+ if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(0)
+ }
+ p := privateKey.(*rsa.PrivateKey)
+ keySize := p.Size()
+ srcSize := len(cipherText)
+ log.Println("密钥长度", keySize, "密文长度", srcSize)
+ var offSet = 0
+ var buffer = bytes.Buffer{}
+ for offSet < srcSize {
+ endIndex := offSet + keySize
+ if endIndex > srcSize {
+ endIndex = srcSize
+ }
+ bytesOnce, err := rsa.DecryptPKCS1v15(rand.Reader, p, cipherText[offSet:endIndex])
+ if err != nil {
+ return nil
+ }
+ buffer.Write(bytesOnce)
+ offSet = endIndex
+ }
+ bytesDecrypt = buffer.Bytes()
+ return bytesDecrypt
+}
+
+// RsaEncryptBlock 公钥加密-分段
+func RsaEncryptBlock(src []byte, path string) (bytesEncrypt []byte, err error) {
+ //打开文件
+ //file, err := os.Open(path)
+ //if err != nil {
+ // return
+ //}
+ //
+ ////读取文件的内容
+ //info, _ := file.Stat()
+ //buf := make([]byte, info.Size())
+ //file.Read(buf)
+
+ // 读取公钥文件
+ keyData, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil,err
+ }
+
+ //pem解码
+ block, _ := pem.Decode(keyData)
+ //x509解码
+ publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
+ if err != nil {
+ fmt.Println(err)
+ }
+ //类型断言
+ publicKey := publicKeyInterface.(*rsa.PublicKey)
+ keySize, srcSize := publicKey.Size(), len(src)
+ log.Println("密钥长度", keySize, "明文长度", srcSize)
+ offSet, once := 0, keySize-11
+ buffer := bytes.Buffer{}
+ for offSet < srcSize {
+ endIndex := offSet + once
+ if endIndex > srcSize {
+ endIndex = srcSize
+ }
+ // 加密一部分
+ bytesOnce, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src[offSet:endIndex])
+ if err != nil {
+ return nil, err
+ }
+ buffer.Write(bytesOnce)
+ offSet = endIndex
+ }
+ bytesEncrypt = buffer.Bytes()
+ return
+}
+
+
func timing(client mqtt.Client) {
//定时器,10秒钟执行一次
ticker := time.NewTicker(5 * time.Second)
@@ -193,6 +403,27 @@ func timing(client mqtt.Client) {
// queryOneDataByMySql(db)
// //mydb.Close()
//}
+
+ //GenerateRSAKey(2048)
+ //publicPath := "public.pem"
+ //privatePath := "private.pem"
+ //
+ //var a = []byte("jack")
+ //encrptTxt, err := RsaEncryptBlock(a, publicPath)
+ //if err != nil {
+ // fmt.Println(err.Error())
+ //}
+ //fmt.Println("加密后的字符串:")
+ //encodeString := base64.StdEncoding.EncodeToString(encrptTxt)
+ //fmt.Println(encodeString)
+ //fmt.Println("-------------------")
+ //decodeByte, err := base64.StdEncoding.DecodeString(encodeString)
+ //if err != nil {
+ // fmt.Println(err.Error())
+ //}
+ //decrptCode := RSA_Decrypts(decodeByte, privatePath)
+ //fmt.Println("解密后的字符串:")
+ //fmt.Println(string(decrptCode))
}
}
}
@@ -203,38 +434,81 @@ var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Me
message := fmt.Sprintf("%s", msg.Payload())
topic := fmt.Sprintf("%s", msg.Topic())
fmt.Println(message)
- result := strings.Split(message, " ")
- fmt.Println(result[0])
- fmt.Println(result[1])
-
- now := time.Now()
- temperature := new(models.Temperature)
- temperature.CreateDate = now
- temperature.DataDate = now.Format("2006-01-02")
- temperature.DataHour = now.Format("2006-01-02 15")
- temperature.DataMinute = now.Format("2006-01-02 15:04")
- temperature.Humidity = result[0]
- temperature.Temperature = result[1]
- temperature.Topic = topic
-
- if topic == "WifiSHT/7C87CE9CA4E6/SHT20" {
- temperature.LocationDesc = "广东省珠海市高新区唐家湾镇东岸村水风三街28号501"
- }
- if topic == "WifiSHT/7C87CE9F5CBF/SHT20" {
- temperature.LocationDesc = "广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房"
- }
- if topic == "WifiSHT/4CEBD686B6AA/SHT20" {
- temperature.LocationDesc = "广西壮族自治区崇左市天等县天等镇荣华村弄在屯113号"
- }
- fmt.Println("测温传感器地点:", temperature.LocationDesc)
-
- //db, err := getMySqlDB()
- //if err == nil {
- // insertDataByMySql(db,temperature)
- // //mydb.Close()
- //}
+ fmt.Println(topic)
+
+
+ privatePath := "privateKey.pem"
+
+ if topic == "app_push" {
+ fmt.Println("珠海电厂APP收到mqtt消息")
+ decodeByte, err := base64.StdEncoding.DecodeString(message)
+ if err != nil {
+ fmt.Println(err.Error())
+ }
+ decrptCode := RSA_Decrypts(decodeByte, privatePath)
+ fmt.Println("解密后的字符串:")
+ fmt.Println(string(decrptCode))
+ fmt.Println("-----user--------")
+ var user models.User
+ json.Unmarshal(decrptCode, &user)
+ fmt.Println(user)
+ //models.SaveUser(&user)
+
+ if models.GetUser(&user) {
+ models.UpdateUser(&user)
+ }else{
+ models.SaveUser(&user)
+ }
+
+ }else if topic == "app_push_dyw" {
+ fmt.Println("大亚湾电厂APP收到mqtt消息")
+ decodeByte, err := base64.StdEncoding.DecodeString(message)
+ if err != nil {
+ fmt.Println(err.Error())
+ }
+ decrptCode := RSA_Decrypts(decodeByte, privatePath)
+ fmt.Println("解密后的字符串:")
+ fmt.Println(string(decrptCode))
+ fmt.Println("-----user--------")
+ //var user models.User
+ //json.Unmarshal(decrptCode, &user)
+ //fmt.Println(user)
+ //
+ //if models.GetUser(&user) {
+ // models.UpdateUser(&user)
+ //}else{
+ // models.SaveUser(&user)
+ //}
+
+ }else{
+ result := strings.Split(message, " ")
+ fmt.Println(result[0])
+ fmt.Println(result[1])
+
+ now := time.Now()
+ temperature := new(models.Temperature)
+ temperature.CreateDate = now
+ temperature.DataDate = now.Format("2006-01-02")
+ temperature.DataHour = now.Format("2006-01-02 15")
+ temperature.DataMinute = now.Format("2006-01-02 15:04")
+ temperature.Humidity = result[0]
+ temperature.Temperature = result[1]
+ temperature.Topic = topic
+ if topic == "WifiSHT/7C87CE9CA4E6/SHT20" {
+ temperature.LocationDesc = "广东省珠海市高新区唐家湾镇东岸村水风三街28号501"
+ }
+ if topic == "WifiSHT/7C87CE9F5CBF/SHT20" {
+ temperature.LocationDesc = "广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房"
+ }
+ if topic == "WifiSHT/4CEBD686B6AA/SHT20" {
+ temperature.LocationDesc = "广西壮族自治区崇左市天等县天等镇荣华村弄在屯113号"
+ }
+ fmt.Println("测温传感器地点:", temperature.LocationDesc)
+ models.SaveTemperature(temperature)
+ }
+
+
- models.SaveTemperature(temperature)
//uuid := uuid.New()
//models.SaveProduct()
@@ -267,6 +541,8 @@ var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Me
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
fmt.Println("Connected")
subTemperature(client)
+ subAppPush(client)
+ subAppPushDyw(client)
}
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
@@ -287,6 +563,20 @@ func subTemperature(client mqtt.Client) {
fmt.Printf("Subscribed to topic: %s", topic)
}
+func subAppPush(client mqtt.Client) {
+ topic := "app_push"
+ token := client.Subscribe(topic, 2, nil)
+ token.Wait()
+ fmt.Printf("Subscribed to topic: %s", topic)
+}
+func subAppPushDyw(client mqtt.Client) {
+ topic := "app_push_dyw"
+ token := client.Subscribe(topic, 2, nil)
+ token.Wait()
+ fmt.Printf("Subscribed to topic: %s", topic)
+}
+
+
func publish(client mqtt.Client) {
num := 999999000000000000
for i := 0; i < num; i++ {
@@ -324,6 +614,8 @@ func main() {
//sub(client)
subTemperature(client)
+ subAppPush(client)
+ subAppPushDyw(client)
publish(client)
//client.Disconnect(1000)
diff --git a/models/User.go b/models/User.go
new file mode 100644
index 0000000..38e55b0
--- /dev/null
+++ b/models/User.go
@@ -0,0 +1,76 @@
+package models
+
+import (
+ "errors"
+ "fmt"
+ "go_mqtt/mydb"
+ "gorm.io/gorm"
+)
+
+type User struct {
+ Username string `gorm:"primaryKey;size:255"`
+ Password string `gorm:"size:255"`
+ Date string `gorm:"size:255"`
+ Imeinum string `gorm:"size:50"`
+ Sysversion string `gorm:"size:100"`
+ Phonemodel string `gorm:"size:255"`
+ Appversion string `gorm:"size:255"`
+ Name string `gorm:"size:255"`
+}
+
+func init() {
+ fmt.Println("User init()")
+ mydb.DB.AutoMigrate(&User{})
+}
+
+// TableName 会将 User 的表名重写为 `user`
+func (User) TableName() string {
+ return "user"
+}
+
+func SaveUser(user *User) {
+ result := mydb.DB.Create(&user)
+ if result.Error != nil {
+ fmt.Println("Failed to create User:", result.Error)
+ } else {
+ fmt.Println("User created successfully!")
+ }
+}
+
+func UpdateUser(item *User) {
+ fmt.Println("用户存在,更新操作")
+ var user User
+ mydb.DB.First(&user, item.Username)
+ user.Password=item.Password
+ user.Date=item.Date
+ user.Imeinum=item.Imeinum
+ user.Sysversion=item.Sysversion
+ user.Phonemodel=item.Phonemodel
+ user.Appversion=item.Appversion
+ user.Name=item.Name
+ mydb.DB.Save(&user)
+}
+
+func GetUser(item *User) bool {
+ var user User
+ //mydb.DB.First(&user, item.Username)
+
+
+
+ result := mydb.DB.First(&user, item.Username).Error
+ fmt.Println("-----user---->>")
+ fmt.Println(user)
+
+ if errors.Is(result, gorm.ErrRecordNotFound) {
+ // 记录不存在
+ fmt.Println("用户不存在")
+ } else if result == nil {
+ // 记录存在
+ fmt.Println("用户存在")
+ return true
+ } else {
+ // 其他错误
+ fmt.Println("查询出错")
+ }
+ return false
+}
diff --git a/mydb/initialize.go b/mydb/initialize.go
index dae5643..89bd764 100755
--- a/mydb/initialize.go
+++ b/mydb/initialize.go
@@ -19,8 +19,8 @@ func initDatabase() {
//dsn := "root:Skyinno251,@tcp(192.168.2.18:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
//dsn := "root:Skyinno251,@tcp(47.242.184.139:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
- //dsn := "root:Skyinno251,@tcp(localhost:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
- dsn := "root:Skyinno251,@tcp(192.168.3.29:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
+ dsn := "root:Skyinno251,@tcp(localhost:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
+ //dsn := "root:Skyinno251,@tcp(192.168.3.29:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: dsn, // DSN data source name
diff --git a/privateKey.pem b/privateKey.pem
new file mode 100644
index 0000000..cebbd43
--- /dev/null
+++ b/privateKey.pem
@@ -0,0 +1,3 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCYwvInDUICXbmWcOAR5hm86mz7WlKL3dDf12MSeIY2jm5QpUSSoMhrJOWLbOt5fXQepPaNO0M30A+3C4SFZrM/9WA5ehazO1u1m1LAkYzoSDRH3MMJsrJC3lCGDeOROteu+safuP9k/npU1YQu/+Ll2xEJNxyvUx4jLGM4LamiMI6ytM3gdnOAGP4YRQo9Etwo6I986yg/seCQC5rza9M4iBamoin7U8h9yOMKrM6xK/k9CcY/vn5+Uhe3Pvk4qj/2Ff3OXkkc1wfdILqdLwLOKL0Tb3ZciwG0p1CKO80yf5hyYoWjqZk5Rcd07nTo2gqTFGfLl9sqI9/+ipMDtnHlAgMBAAECggEATJd5yCC6lusdMRO5FOBUyUaUi9X2i1AU+RZKAynQySvSnbavUgExW58tRCHBUrGW9gJp59ft1N8J8hHhSO18NDY4H7laBlVdnwmYjRqtFo2VQO6sD4G8JRDION5f2iIxn/b2fYDI9H8vILfJRbNgtTSILyGlzTYUZzhLKxCh+8IsN96Nic8wa5COd1vZZmdhf2y8TG8clFWmozaScNSAATx7y+8XLVWjjWiIRZ6xQvx0uQPUParc9KihXXTKR2pA22yPIdz+U4MGD4kC0eczlcFKZ/dYv9e7OIGgnJfT0idSCu7nYb1pxJ1LxD9fS6IScNTF5dSe0OIL98e+XdyoAQKBgQDRep+5cW4iAKrEMH+djmcXAkoMiYtNVtnu0efLE8dP6vjYytQi368X9SdcASbfrQ31eEZmr/xQnlUF8oyHGkI38YS8dpAHzQcrkP3BljbbzB/3gJZaUdghGsDrK0xAJIzzmFKQpeKnGtr23vxUgaGrNsCYvQ0eQ7+5056KXS4r5QKBgQC6r8xtRSaje6L4WIydjWvYywsmRO0Of0aJLMDA/Wt2MWhHfh7ba9oI1cKGN80ap7xB2a9lQLgpv+C53wNtE5SpvjxsikAj96nUMMhGy9ojXrUith6HQhiINETz6Shnznd+AyrXP6KI/RpfA5nkDB5nrJxODwtYLP467IL7Cv7OAQKBgQCl4KxKdH/5fP28jYsAgJsxpSZt9xzQCU5Zxu396ZOSvUaApVyGoQpNtluMh3z48lhzYOKevgzW6gn5w69z7F8zXZT2iAxVoQ1kelP2z7RxKJrHqpNkwhqbXEwX7RlcUZUr8BqxYCqymJl7k+fMIzqaEalBSbLxnEReKi0I8/Bz4QKBgHK4b0ZCtVDHPEmimJ6E9l4dv/c/afF7swu+zaCK2ouiJvOwBCRQbYb6XPR/u/GCXASXUdpF4CX/vIhcDE3uN2/r8FO+zVWM7vbvF1OyF5WesG7pPW9e5ZZlkG3WvLa1wOZV6fCmMSo/ZwI2Q05JSDHrd43cXttLotrw1jiQ9C4BAoGBAKi4SOoOVQ5J5HQCDkBwPbG1AOLHFinzfoDl26GF/8Hy7fmmd1JiRTFldQp/A9VTAABz3sVYmMB92HSIaJhuDMoYJNI2Cf/cZifsv7vUL8cbLn+lPsKsebiuB0m0g4P2qLwLfegfNGEgA7lA5HIz3SELqbdp3iuqJeQl1fsJqD74
+-----END PRIVATE KEY-----