Browse Source

debug

master
linquan 4 months ago
parent
commit
74ec34597b
  1. 0
      TapOpenId.json
  2. 1
      api/v1/game/advertisement.go
  3. 273
      caid.go
  4. 1
      internal/controller/game_pub.go
  5. 6
      internal/serviceGame/advertisement.go
  6. 61
      internal/serviceGame/internal/advertisement.go
  7. 331
      internal/serviceGame/internal/caid/caid.go
  8. 16
      manifest/config/dev_10702/pkcs8_private.pem
  9. 18
      manifest/config/dev_10702/private_key.pem
  10. 11
      manifest/config/dev_10702/pub_for_sdk.cer
  11. 6
      manifest/config/dev_10702/public_for_api.pem
  12. BIN
      manifest/config/dev_10702/public_key.der
  13. 436
      test/caid.go

0
test/TapOpenId.json → TapOpenId.json

1
api/v1/game/advertisement.go

@ -110,7 +110,6 @@ type AdvertiseHAReq struct {
Idfa string `p:"idfa"` Idfa string `p:"idfa"`
PackageName string `p:"package_name"` PackageName string `p:"package_name"`
Properties string `p:"properties"` Properties string `p:"properties"`
UnitId string `p:"unitId"`
Caid string `p:"caid"` Caid string `p:"caid"`
} }

273
caid.go

@ -0,0 +1,273 @@
package main
import (
"bytes"
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"github.com/gogf/gf/v2/encoding/gcharset"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"io"
"io/ioutil"
"log"
"math/big"
)
const pubKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCk2GwklLJO0m4Z5PffSSRlv7jNkQhFyoESukIu2duXN9YaC9G7SCQQnyHYs1Si/W4z/u5a4OXBE5+jZ9W9zmc1wfVelf2vnzTfKABA6AJhlsUXs2UjPQrxNRCgu4rALQ2TlbobqqLpIWtm5rqboXs3yJpRfgaLlJvAdihxx2XYQIDAQAB"
const maxDecryptBlock = 128
func main() {
// 设备公共信息
deviceInfo := map[string]string{
"bootTimeInSec": "1595643553",
"countryCode": "CN",
"language": "zh-Hans-CN",
"deviceName": "e910dddb2748c36b47fcde5dd720eec1",
"systemVersion": "14.0",
"machine": "iPhone10,3",
"memory": "3955589120",
"disk": "63900340224",
"sysFileTime": "1595214620.383940",
"model": "D22AP",
"timeZone": "28800",
"deviceInitTime": "1632467920.301150749",
}
// 公钥字符串,注意需要剔除换行符
//PUBK := pubKeyBase64 // 分配的API接入的公钥字符串
//privateKey, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem")
//if err != nil {
// fmt.Println(err)
// return
//}
// 序列化设备信息为JSON
jsonBytes, err := json.Marshal(deviceInfo)
if err != nil {
fmt.Printf("JSON序列化错误: %v\n", err)
return
}
jsonStr := string(jsonBytes)
// 加密设备信息
encryptedDeviceByte, err := encrypt(jsonStr)
if err != nil {
fmt.Printf("加密错误 encrypt: %v\n", err)
return
}
fmt.Printf("加密后的设备信息: encryptedDeviceByte: %s\n", encryptedDeviceByte)
ctx := context.TODO()
url := "https://caid.china-caa.org/v1.0/get"
data := map[string]interface{}{"dev_id": "10702", "encrypted_device_info": "mbJbTVF1b2m/4i59seIcqAizHHwtt4oMXOXmXKREqaGdVnDKrllvQlNiCt0xpazhcmrzs5aJP9nkEaeuI3omZvdOc1dSJG4oQPPE5X49ErfQL4IT867QzqFPt7AoYtV0DfGarTWwiUPo8JTcIdQBwL7bKgoog93qj8xl/q3y80tgyjVUfQPPWS/UVPfTzMy/lazKm1qY5SIHkm6vJDaUPSC3d4kEQdpicZo1H5cjeCyukP16O5t2PsksTqMJHOg62UIRO6zTNL0Q14+YWfmEaAeUiQrjH8nAfh+Jx3/N3CkcGAJOPrbCRCgfmSIwQ2F6D/pjQd3BNuSKB9W/a+PljRaA54reu0+2L0KJnfhmPXnqltLEclV1PGORYcx5cDK/tbfeXmmvLuPtroH1Dd/+Kc0hz5t2BAHiCh9M6kSqDOXF0muQIM6Mfc473F/uEeiwLZdQ6QbpYdXPYoB+jzQXrDkblpTWhBw4NKdEhR2o2sjVK73YP9BQHmEohzblfHCJ"}
g.Client().SetHeader("Content-Type", "application/json")
g.Client().SetHeader("Cache-Control", "no-cache")
log.Printf("sendMsgHugeAmount - url: %s, data: %s", url, gjson.MustEncodeString(data))
marshal, _ := json.Marshal(data)
bytes, err := g.Client().Post(ctx, url, string(marshal))
if err != nil {
return
}
src := string(bytes.ReadAll())
tmp, err := gcharset.ToUTF8("UTF-8", src)
if err != nil {
return
}
fmt.Println("Deposit - json: ", tmp)
////tmp, err := SendCaidMsg(ctx, url, data)
//if err != nil {
// fmt.Println("SendCaidMsg err:", err)
// return
//}
//resJson, err := gjson.DecodeToJson(tmp)
//if err != nil {
// fmt.Println("SendCaidMsg DecodeToJson err:", err)
// return
//}
//if resJson != nil && resJson.Get("code").Int() != 0 {
// fmt.Println("SendCaidMsg err:", resJson.Get("message").String())
// return
//}
caid := "J5LdxnMrcpDiNrn2QLZvCPavphS9nUqu7uwCEjLkEvtP2blwhevgGvQD7AKajkEc+PIC2TuIFxbSGK9Jsm27CrsW446pi+gIIc3OdKB4jqQJoDD77BbJC3I105DnsEwgR8uLvSVy0NgqFq+rf4GRYwp93Jy2eZdDKkS+Y0BgTEQkedK1P29hyYEELLQzvJrq9XlwfYx1QcGGcofZmq56B65IbQQfRvoXAiSl2cm12qFkpD8KbPmvy66xE6yu3SFAMC6iAEdfW4W8hz0Qv9Bht2nhDxsm4c39z1mU41s1oP5lJ5kkUl4yU3NWRO19jIYOm8lMJb19oDc+weBaMkgIbQ=="
fmt.Println("Deposit - caid: ", caid)
//encryptedDeviceInfo, err := encryptWithPublicKey(jsonStr, vm.publicKey)
//if err != nil {
// fmt.Printf("加密错误 encryptWithPublicKey: %v\n", err)
// return
//}
// 将encryptedDeviceInfo填入请求中的encrypted_device_info字段
// 解密响应数据示例
// 假设从响应中获取的data字段值
//fmt.Printf("解密后的响应数据: %s\n ,decryptedByte: %s\n", decryptedData, string(decryptedByte))
}
// 使用公钥加密数据
func encryptWithPublicKey(data string, rsaPubKey *rsa.PublicKey) (string, error) {
//// 解码Base64格式的公钥
//pubKeyBytes, err := base64.StdEncoding.DecodeString(pubKeyStr)
//if err != nil {
// return "", fmt.Errorf("公钥Base64解码错误: %v", err)
//}
//
//// 解析公钥
//publicKey, err := x509.ParsePKIXPublicKey(pubKeyBytes)
//if err != nil {
// return "", fmt.Errorf("公钥解析错误: %v", err)
//}
//
//// 断言为RSA公钥
//rsaPubKey, ok := publicKey.(*rsa.PublicKey)
//if !ok {
// return "", errors.New("不是RSA公钥")
//}
// 计算最大加密块大小
maxEncryptBlock := rsaPubKey.Size() - 42 // PKCS#1 OAEP加密需要预留42字节
dataBytes := []byte(data)
dataLen := len(dataBytes)
var encryptedBytes []byte
// 分段加密
for i := 0; i < dataLen; i += maxEncryptBlock {
end := i + maxEncryptBlock
if end > dataLen {
end = dataLen
}
// 加密当前块
encryptedBlock, err := rsa.EncryptOAEP(
nil,
rand.Reader,
rsaPubKey,
dataBytes[i:end],
nil,
)
if err != nil {
return "", fmt.Errorf("加密错误: %v", err)
}
encryptedBytes = append(encryptedBytes, encryptedBlock...)
}
// Base64编码加密结果
return base64.StdEncoding.EncodeToString(encryptedBytes), nil
}
func ImportSPKIPublicKeyPEM() *rsa.PublicKey {
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem")
if err != nil {
fmt.Println(err)
}
fmt.Printf("encrypt pubKeyBytes: %s\n", string(pubKeyBytes))
body, _ := pem.Decode(pubKeyBytes)
fmt.Printf(" body.Bytes : %s\n byte: %s\n", body.Type, body.Bytes)
publicKey, _ := x509.ParsePKIXPublicKey(body.Bytes)
if publicKey, ok := publicKey.(*rsa.PublicKey); ok {
return publicKey
} else {
return nil
}
}
func encrypt(data string) (string, error) {
//raw, err := base64.StdEncoding.DecodeString(data)
//if err != nil {
// return nil, fmt.Errorf("base64 decode %w: %s", err, data)
//}
pubKey := ImportSPKIPublicKeyPEM()
fmt.Printf("data: len: %d\n pubkey: %v\n", len(data), pubKey)
maxEncryptBlock := 117
//ciphertextBytes, _ := base64.StdEncoding.DecodeString(data)
reader := bytes.NewReader([]byte(data))
var writer bytes.Buffer
ciphertextBytesChunk := make([]byte, maxEncryptBlock)
fmt.Println("chunk: ", len([]byte(data)), len(ciphertextBytesChunk))
for {
n, _ := io.ReadFull(reader, ciphertextBytesChunk)
if n == 0 {
fmt.Println("chunk: n ", n)
break
}
encryptChunk(ciphertextBytesChunk, &writer, pubKey)
fmt.Println("chunk: ", len(ciphertextBytesChunk))
}
// Concatenate decrypted signature chunks
decryptedData := writer.String()
fmt.Println(decryptedData)
//reader := bytes.NewReader([]byte(data))
//var writer bytes.Buffer
//chunk := make([]byte, maxEncryptBlock)
//fmt.Println("chunk: ", len(chunk))
//for {
// n, err := io.ReadFull(reader, chunk)
// if err != nil && errors.Is(err, io.ErrUnexpectedEOF) {
// return nil, fmt.Errorf("read encrypt data: %w", err)
// }
// if n == 0 {
// break
// }
// encryptChunk(chunk, &writer, pubKey)
//}
output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n")
if bytes.Count(output, []byte("\x00")) > 0 {
after := bytes.ReplaceAll(output, []byte("\x00"), []byte{})
log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after)
output = after
}
//return output, nil
return string(output), nil
}
func encryptChunk(ciphertextBytesChunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) {
// Decrypt each signature chunk
ciphertextInt := new(big.Int)
ciphertextInt.SetBytes(ciphertextBytesChunk)
decryptedPaddedInt := doEncrypt(new(big.Int), pubKey, ciphertextInt)
// Remove padding
decryptedPaddedBytes := make([]byte, pubKey.Size())
decryptedPaddedInt.FillBytes(decryptedPaddedBytes)
start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00
decryptedBytes := decryptedPaddedBytes[start:]
// Write decrypted signature chunk
writer.Write(decryptedBytes)
}
func doEncrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
// Textbook RSA
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
//func encryptChunk(chunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) {
// // Decrypt each signature chunk
// ciphertextInt := new(big.Int)
// ciphertextInt.SetBytes(chunk)
// decryptedPaddedInt := doEncrypt(new(big.Int), pubKey, ciphertextInt)
// // Remove padding
// decryptedPaddedBytes := make([]byte, pubKey.Size())
// decryptedPaddedInt.FillBytes(decryptedPaddedBytes)
// start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00
// decryptedBytes := decryptedPaddedBytes[start:]
// // Write decrypted signature chunk
// writer.Write(decryptedBytes)
//}
//
//func doEncrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
// // Textbook RSA
// e := big.NewInt(int64(pub.E))
// c.Exp(m, e, pub.N)
// return c
//}

1
internal/controller/game_pub.go

@ -138,6 +138,7 @@ func (c *pubController) ConversionHugeAmount(ctx context.Context, req *game.CSHA
func (c *pubController) AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *game.AdvertiseHARes, err error) { func (c *pubController) AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *game.AdvertiseHARes, err error) {
//log.Print("AdvertiseHugeAmount", gjson.MustEncodeString(req)) //log.Print("AdvertiseHugeAmount", gjson.MustEncodeString(req))
//return
res, err = serviceGame.Advertisement().AdvertiseHugeAmount(ctx, req) res, err = serviceGame.Advertisement().AdvertiseHugeAmount(ctx, req)
return return
} }

6
internal/serviceGame/advertisement.go

@ -61,7 +61,7 @@ func (g *advertisementImpl) AdvertiseHugeAmount(ctx context.Context, req *game.A
return return
} }
func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId, idfa, os, callBack, timestamp, caidlist, ip string) (err error) { func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId, idfa, os, callBack, timestamp, caidList, ip string) (err error) {
osInt, err := strconv.Atoi(os) osInt, err := strconv.Atoi(os)
if err != nil { if err != nil {
return return
@ -76,9 +76,9 @@ func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId,
return return
} }
caid := "" caid := ""
if caidlist != "" { if caidList != "" {
var list []map[string]string var list []map[string]string
_ = json.Unmarshal([]byte(caidlist), &list) _ = json.Unmarshal([]byte(caidList), &list)
versionNow := int64(0) versionNow := int64(0)
for _, v := range list { for _, v := range list {
version, _ := strconv.ParseInt(v["version"], 10, 64) version, _ := strconv.ParseInt(v["version"], 10, 64)

61
internal/serviceGame/internal/advertisement.go

@ -17,6 +17,7 @@ import (
"tyj_admin/internal/dao" "tyj_admin/internal/dao"
"tyj_admin/internal/model/do" "tyj_admin/internal/model/do"
"tyj_admin/internal/model/entity" "tyj_admin/internal/model/entity"
"tyj_admin/internal/serviceGame/internal/caid"
) )
func Advertise(ctx context.Context, req *game.ADReq) (res *game.ADRes, err error) { func Advertise(ctx context.Context, req *game.ADReq) (res *game.ADRes, err error) {
@ -303,7 +304,9 @@ func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSH
resJson, err := gjson.DecodeToJson(tmp) resJson, err := gjson.DecodeToJson(tmp)
if resJson != nil && resJson.Get("code").Int() != 0 { if resJson != nil && resJson.Get("code").Int() != 0 {
err = errors.New(resJson.Get("message").String()) err = errors.New(resJson.Get("message").String())
} } /*else if resJson.Get("code").Int() == 0 {
dao.AdvertisementOceanegine.Ctx(ctx).Where("id=?", adData[0].Id).Update(do.AdvertisementOceanegine{})
}*/
return return
} }
@ -315,19 +318,51 @@ func AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *ga
if req.Platform == "iphoneplayer" { if req.Platform == "iphoneplayer" {
req.Platform = "ios" req.Platform = "ios"
} }
go HugeAmount(ctx, req) go HugeAmount(ctx, req)
return return
} }
func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) { func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) {
if req.Platform == "ios1" {
//url := "https://caid.china-caa.org/v1.0/get"
//data := map[string]interface{}{"dev_id": "10702", "encrypted_device_info": caid.EncryptDeviceInfo()}
//tmp, err := SendCaidMsg(ctx, url, data)
//if err != nil {
// fmt.Println("SendCaidMsg err:", err)
// return
//}
//resJson, err := gjson.DecodeToJson(tmp)
//if err != nil {
// fmt.Println("SendCaidMsg DecodeToJson err:", err)
// return
//}
//if resJson != nil && resJson.Get("code").Int() != 0 {
// fmt.Println("SendCaidMsg err:", resJson.Get("message").String())
// return
//}
//req.Caid = resJson.Get("data").String()
if req.Caid != "" {
decryptedByte, err := caid.Decrypt(req.Caid)
if err != nil {
log.Printf("Decrypt err: %s", err.Error())
return
}
req.Caid = string(decryptedByte)
}
log.Printf("HugeAmount req2: %s", gjson.MustEncodeString(req))
return
}
req2 := game.CSHAReq{ req2 := game.CSHAReq{
Platform: req.Platform, Platform: req.Platform,
Id: req.Id, Id: req.Id,
Idfa: req.Idfa, Idfa: req.Idfa,
EventType: req.EventType, EventType: req.EventType,
Properties: req.Properties, Properties: req.Properties,
UnitId: req.UnitId,
Caid: req.Caid, Caid: req.Caid,
//UnitId: req.UnitId,
} }
req2.Id = req.Id req2.Id = req.Id
_, err := ConversionHugeAmount(ctx, &req2) _, err := ConversionHugeAmount(ctx, &req2)
@ -338,9 +373,9 @@ func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) {
req1 := game.ATHAReq{ req1 := game.ATHAReq{
Platform: req.Platform, Platform: req.Platform,
PackageName: req.PackageName, PackageName: req.PackageName,
Idfa: req.Idfa,
UnitId: req.UnitId,
Caid: req.Caid, Caid: req.Caid,
Idfa: req.Idfa,
//UnitId: req.UnitId,
} }
if req.Platform == "android" { if req.Platform == "android" {
req1.AndroidId = req.Id req1.AndroidId = req.Id
@ -468,3 +503,21 @@ func GetCostReport(ctx context.Context, req *game.GetCostReportReq) (res *game.G
} }
return res, err return res, err
} }
func SendCaidMsg(ctx context.Context, url string, data map[string]interface{}) (string, error) {
g.Client().SetHeader("Content-Type", "application/json")
g.Client().SetHeader("Cache-Control", "no-cache")
log.Printf("sendMsgHugeAmount - url: %s, data: %s", url, gjson.MustEncodeString(data))
marshal, _ := json.Marshal(data)
bytes, err := g.Client().Post(ctx, url, string(marshal))
if err != nil {
return "", err
}
src := string(bytes.ReadAll())
tmp, err := gcharset.ToUTF8("UTF-8", src)
if err != nil {
return "", err
}
fmt.Println("Deposit - json: ", tmp)
return tmp, err
}

331
internal/serviceGame/internal/caid/caid.go

@ -0,0 +1,331 @@
package caid
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"math/big"
)
const maxDecryptBlock = 128
//
//func Decrypt(data string) ([]byte, error) {
// raw, err := base64.StdEncoding.DecodeString(data)
// if err != nil {
// return nil, fmt.Errorf("base64 decode %w: %s", err, data)
// }
// // 初始化ViewModel
// vm, err := NewViewModel()
// if err != nil {
// log.Printf("初始化失败: %v", err)
// return nil, fmt.Errorf("base64 decode %w: %s", err, data)
// }
// reader := bytes.NewReader(raw)
// var writer bytes.Buffer
// chunk := make([]byte, maxDecryptBlock)
// for {
// n, err := io.ReadFull(reader, chunk)
// if err != nil && errors.Is(err, io.ErrUnexpectedEOF) {
// return nil, fmt.Errorf("read decrypted data: %w", err)
// }
// if n == 0 {
// break
// }
// pubKey := vm.publicKey
// decryptChunk(chunk, &writer, pubKey)
// }
// output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n")
// if bytes.Count(output, []byte("\x00")) > 0 {
// after := bytes.ReplaceAll(output, []byte("\x00"), []byte{})
// log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after)
// output = after
// }
// return output, nil
//}
//
//func decryptChunk(chunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) {
// // Decrypt each signature chunk
// ciphertextInt := new(big.Int)
// ciphertextInt.SetBytes(chunk)
// decryptedPaddedInt := doDecrypt(new(big.Int), pubKey, ciphertextInt)
// // Remove padding
// decryptedPaddedBytes := make([]byte, pubKey.Size())
// decryptedPaddedInt.FillBytes(decryptedPaddedBytes)
// start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00
// decryptedBytes := decryptedPaddedBytes[start:]
// // Write decrypted signature chunk
// writer.Write(decryptedBytes)
//}
//
//func doDecrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
// // Textbook RSA
// e := big.NewInt(int64(pub.E))
// c.Exp(m, e, pub.N)
// return c
//}
// ViewModel 处理业务逻辑的视图模型
type ViewModel struct {
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
}
// NewViewModel 初始化视图模型
func NewViewModel() (*ViewModel, error) {
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem")
if err != nil {
fmt.Println(err)
}
fmt.Printf("pubKeyBytes: %s", pubKeyBytes)
block, _ := pem.Decode(pubKeyBytes)
if block != nil {
pubKeyBytes = block.Bytes
}
fmt.Printf("pubKeyBytes: %s", fmt.Sprint(pubKeyBytes))
pubKey, err := x509.ParsePKIXPublicKey(pubKeyBytes)
if err != nil {
return nil, fmt.Errorf("解析公钥失败: %w", err)
}
rsaPubKey, ok := pubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("无效的RSA公钥类型1")
}
return &ViewModel{publicKey: rsaPubKey}, nil
}
// EncryptDeviceInfo 加密设备信息
func (vm *ViewModel) EncryptDeviceInfo(deviceInfo map[string]string) (string, error) {
jsonData, err := json.Marshal(deviceInfo)
if err != nil {
return "", fmt.Errorf("JSON序列化失败: %w", err)
}
plaintext := string(jsonData)
maxBlockSize := vm.publicKey.Size() - 11 // PKCS#1 v1.5填充最大块大小
fmt.Println("EncryptDeviceInfo", maxBlockSize, len(jsonData), len(plaintext))
var encryptedBlocks [][]byte
for i := 0; i < len(plaintext); i += maxBlockSize {
end := i + maxBlockSize
if end > len(plaintext) {
end = len(plaintext)
}
block := []byte(plaintext[i:end])
encryptedBlock, err := rsa.EncryptPKCS1v15(rand.Reader, vm.publicKey, block)
if err != nil {
return "", fmt.Errorf("RSA加密失败: %w", err)
}
encryptedBlocks = append(encryptedBlocks, encryptedBlock)
fmt.Printf("EncryptDeviceInfo encryptedBlocks: %s, encryptedBlock: %s, block: %s \n", encryptedBlocks, string(encryptedBlock), string(block))
}
return base64.StdEncoding.EncodeToString(bytesJoin(encryptedBlocks)), nil
}
// DecryptResponse 解密响应数据
func (vm *ViewModel) DecryptResponse(ciphertextBase64 string) (string, error) {
ciphertextBytes, err := base64.StdEncoding.DecodeString(ciphertextBase64)
if err != nil {
return "", fmt.Errorf("响应数据Base64解码失败: %w", err)
}
maxBlockSize := vm.privateKey.Size()
var decryptedBlocks [][]byte
for i := 0; i < len(ciphertextBytes); i += maxBlockSize {
end := i + maxBlockSize
if end > len(ciphertextBytes) {
end = len(ciphertextBytes)
}
block := ciphertextBytes[i:end]
decryptedBlock, err := rsa.DecryptPKCS1v15(rand.Reader, vm.privateKey, block)
if err != nil {
return "", fmt.Errorf("RSA解密失败: %w", err)
}
decryptedBlocks = append(decryptedBlocks, decryptedBlock)
}
return string(bytesJoin(decryptedBlocks)), nil
}
// 辅助函数:合并字节切片
func bytesJoin(s [][]byte) []byte {
var totalLen int
for _, b := range s {
totalLen += len(b)
}
res := make([]byte, totalLen)
for i, b := range s {
copy(res[i:], b)
}
return res
}
func EncryptDeviceInfo() string {
// 设备公共信息
deviceInfo := map[string]string{
"bootTimeInSec": "1595643553",
"countryCode": "CN",
"language": "zh-Hans-CN",
"deviceName": "e910dddb2748c36b47fcde5dd720eec1",
"systemVersion": "14.0",
"machine": "iPhone10,3",
"memory": "3955589120",
"disk": "63900340224",
"sysFileTime": "1595214620.383940",
"model": "D22AP",
"timeZone": "28800",
"deviceInitTime": "1632467920.301150749",
}
// 初始化ViewModel
vm, err := NewViewModel()
if err != nil {
log.Printf("初始化失败: %v", err)
return ""
}
// 加密设备信息
encryptedDeviceInfo, err := vm.EncryptDeviceInfo(deviceInfo)
if err != nil {
log.Printf("设备信息加密失败: %v", err)
return ""
}
fmt.Printf("加密设备信息: %s\n", encryptedDeviceInfo)
// 模拟响应解密(使用加密结果模拟响应数据)
//responseData := encryptedDeviceInfo // 实际应从接口获取encrypted_device_info字段
return encryptedDeviceInfo
}
func main1() {
// 设备公共信息
deviceInfo := map[string]string{
"bootTimeInSec": "1595643553",
"countryCode": "CN",
"language": "zh-Hans-CN",
"deviceName": "e910dddb2748c36b47fcde5dd720eec1",
"systemVersion": "14.0",
"machine": "iPhone10,3",
"memory": "3955589120",
"disk": "63900340224",
"sysFileTime": "1595214620.383940",
"model": "D22AP",
"timeZone": "28800",
"deviceInitTime": "1632467920.301150749",
}
// 初始化ViewModel
vm, err := NewViewModel()
if err != nil {
log.Fatalf("初始化失败: %v", err)
}
// 加密设备信息
encryptedDeviceInfo, err := vm.EncryptDeviceInfo(deviceInfo)
if err != nil {
log.Fatalf("设备信息加密失败: %v", err)
}
fmt.Printf("加密设备信息: %s\n", encryptedDeviceInfo)
// 模拟响应解密(使用加密结果模拟响应数据)
responseData := encryptedDeviceInfo // 实际应从接口获取encrypted_device_info字段
// 解密响应数据
decryptedData, err := vm.DecryptResponse(responseData)
if err != nil {
log.Fatalf("响应解密失败: %v", err)
}
fmt.Printf("解密后数据: %s\n", decryptedData)
// 解析JSON数组(示例)
var caidsArray []interface{}
if err := json.Unmarshal([]byte(decryptedData), &caidsArray); err != nil {
log.Fatalf("JSON解析失败: %v", err)
}
fmt.Printf("CAIDs数组: %+v\n", caidsArray)
}
//const maxDecryptBlock = 128
func Decrypt(data string) ([]byte, error) {
raw, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, fmt.Errorf("base64 decode %w: %s", err, data)
}
reader := bytes.NewReader(raw)
var writer bytes.Buffer
chunk := make([]byte, maxDecryptBlock)
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem")
if err != nil {
fmt.Println(err)
}
fmt.Printf("pubKeyBytes: %s\n", pubKeyBytes)
block, _ := pem.Decode(pubKeyBytes)
if block != nil {
pubKeyBytes = block.Bytes
}
fmt.Printf("pubKeyBytes: %s\n", fmt.Sprint(pubKeyBytes))
pubKey, err := x509.ParsePKIXPublicKey(pubKeyBytes)
if err != nil {
return nil, fmt.Errorf("解析公钥失败: %w", err)
}
rsaPubKey, ok := pubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("无效的RSA公钥类型1")
}
for {
n, err := io.ReadFull(reader, chunk)
if err != nil && errors.Is(err, io.ErrUnexpectedEOF) {
return nil, fmt.Errorf("read decrypted data: %w", err)
}
if n == 0 {
break
}
decryptChunk(chunk, &writer, rsaPubKey)
}
output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n")
if bytes.Count(output, []byte("\x00")) > 0 {
after := bytes.ReplaceAll(output, []byte("\x00"), []byte{})
log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after)
output = after
}
fmt.Printf(" output: %s\n", string(output))
return output, nil
}
func decryptChunk(chunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) {
// Decrypt each signature chunk
ciphertextInt := new(big.Int)
ciphertextInt.SetBytes(chunk)
decryptedPaddedInt := doDecrypt(new(big.Int), pubKey, ciphertextInt)
// Remove padding
decryptedPaddedBytes := make([]byte, pubKey.Size())
decryptedPaddedInt.FillBytes(decryptedPaddedBytes)
start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00
decryptedBytes := decryptedPaddedBytes[start:]
// Write decrypted signature chunk
writer.Write(decryptedBytes)
}
func doDecrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
// Textbook RSA
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}

16
manifest/config/dev_10702/pkcs8_private.pem

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKTYbCSUsk7Sbhn
k999JJGW/uM2RCEXKgRK6Qi7Z25c31hoL0btIJBCfIdizVKL9bjP+7lrg5cETn6N
n1b3OZzXB9V6V/a+fNN8oAEDoAmGWxRezZSM9CvE1EKC7isAtDZOVuhuqoukha2b
mupuhezfImlF+BouUm8B2KHHHZdhAgMBAAECgYEAtD9hpPe39zCUF17kTomYYcKW
Npejv1+9DaLzg6JPq54fTL+e5D5xBxKAV87AU/LR27XYBCnEChb0PCon7KEzXSjr
6Mtuv4jeSbL0urTepcHRLzoKpFfwZLC38CrB06DKcJXypxyc482+3heTU3sadkix
nOJhBro4KkyPsErhwo0CQQDlvqlhZhkvHCy+u7vtj6UQGbu7b7UWCX2xZnVpmIa0
cAWNLOJmWPJali5ee5S5hZGdHUrJyQ8Trp4QCTjXkp/rAkEA2M/TRoQ+fJnw9GLw
4E3I8I+UFqOepJn+uVhM+uX/tHTcugyxJAsk+QOmOXgO4Jkb5al984EKdTcNfTS0
PUTe4wJANtrvVnIqUTVI+cGZfX9uygla6cYiVsCtYk40eqIQh8S3jp3I8OcL9tUk
/SpEuIdL3VfBI6z+DJUE6I9LIy2/QQJACysphwho76I+d1hhcCyRnVLIHiJvmasV
JBcYYBRZB8K9XBgrR+ALF4jIl01H9unsNfh1NIYBM+iSGVENt9pEYQJAZHHQ/xwz
+QBFsH8lUKTwP1KyZXAadnfDEBlaaoiT6OsgnuD+JWQv2ztha42nv+49qZfACttY
Nz+3XXhd9HNbgw==
-----END PRIVATE KEY-----

18
manifest/config/dev_10702/private_key.pem

@ -0,0 +1,18 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQI42H/iuHd7KYCAggA
MB0GCWCGSAFlAwQBKgQQtgiHI4QGJWDAP/M32pd7EASCAoAOaP/S8G1+W6oHybzr
aQB2bfCFmFHKD7D5yf5t7gP9aWlG4EPWuIKMpmnXYZenSwE6ZKaezlI4SCmP0qEK
oQ1EAbPMSWS6zfmsXpChTYVUsG+n1049RiQnlqIp+axmSwXJ9yRXCYU3sGtSDDOe
BfCj2CYj1gpVDhjQDwE7TKI2Vk1Pl5Qv2LxpNza71axliU3arLtq7voRsreHK2dQ
8gqAOZle3xpGhk62aoC6B+jQJ8Ha36Uex1HH7nG/eVUfqkocyVfCe1rYaEbf2IbM
xRCF29lPFhBi96ACQm0YMDJJakJ5zYtBJIN1a1fUFxeZI2OLkrb7goIC7vrU1Ffu
q3nVrFtBgYXdOcExzXR7hK0yW/NYE+UsIi1Mr76x+od9tkWkfIuDnUyRsJMkskFv
doKw0xOdo9SINlC+mEJctrNtqBM1DqyaahWqSSh/6LXfF7hYoMXAO07v/mglXP9l
GeJGUE4/wISO8t6N1o21Xl4pHu6XpuFM77lLRP9mL7bD3MKRaHtmk8/uh4wDamSf
GEakQaJ4le1te01NaynAPGbVJpk9EEEvEiqeFPCtgW8fFUuCdq0QdXEbvN3PX3wp
38k9Yc4rTAc51+7+6l1VTLlIz1xGKPAhzOOfqDzH4kCXuilFyXJwhI/h4s2vZ56P
mp0DKHGZ+nim5VPVOs5IYpG5RBTMikmrb5NQZGEHRzYUD3cFx4ehnWAnyptjlS5R
hzlb/1ofuhiwm7STQuYiE+1CgvB8xmLPWNbYv0JNdDqVk63fvyj1GTZsI7F5MTx1
EZ0s0plncM4IfdZlvv06ZtXVd2M6OxxMYjPyN7nFQo5kLolEmAwQDxJdFGJo/n4C
9UZ1
-----END ENCRYPTED PRIVATE KEY-----

11
manifest/config/dev_10702/pub_for_sdk.cer

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBkDCB+gIJAJhAVB+RxnKbMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAYTAkNO
MB4XDTI1MDMxMDA5MzUxNFoXDTI1MDQwOTA5MzUxNFowDTELMAkGA1UEBhMCQ04w
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMKTYbCSUsk7Sbhnk999JJGW/uM2
RCEXKgRK6Qi7Z25c31hoL0btIJBCfIdizVKL9bjP+7lrg5cETn6Nn1b3OZzXB9V6
V/a+fNN8oAEDoAmGWxRezZSM9CvE1EKC7isAtDZOVuhuqoukha2bmupuhezfImlF
+BouUm8B2KHHHZdhAgMBAAEwDQYJKoZIhvcNAQELBQADgYEATv0xjo7a/opVlI2e
GmKa7o/xi9SXwgPFjo/70JT7UHLlS13s3h6iFMRw+z7M4Jxe/MeiA28YbzDeQHDp
p4czxirvBOjfGEnuqc8nwZBLX1CaIGaooyzoS60zrGVdS9xPU5ICysq/IkF1Af/5
719PDABMAAVH5I62Lmzn6pyWCEo=
-----END CERTIFICATE-----

6
manifest/config/dev_10702/public_for_api.pem

@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCk2GwklLJO0m4Z5PffSSRlv7j
NkQhFyoESukIu2duXN9YaC9G7SCQQnyHYs1Si/W4z/u5a4OXBE5+jZ9W9zmc1wfV
elf2vnzTfKABA6AJhlsUXs2UjPQrxNRCgu4rALQ2TlbobqqLpIWtm5rqboXs3yJp
RfgaLlJvAdihxx2XYQIDAQAB
-----END PUBLIC KEY-----

BIN
manifest/config/dev_10702/public_key.der

Binary file not shown.

436
test/caid.go

@ -0,0 +1,436 @@
package main
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"math/big"
)
const pubKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCk2GwklLJO0m4Z5PffSSRlv7jNkQhFyoESukIu2duXN9YaC9G7SCQQnyHYs1Si/W4z/u5a4OXBE5+jZ9W9zmc1wfVelf2vnzTfKABA6AJhlsUXs2UjPQrxNRCgu4rALQ2TlbobqqLpIWtm5rqboXs3yJpRfgaLlJvAdihxx2XYQIDAQAB"
const maxDecryptBlock = 256
func decrypt(data string) ([]byte, error) {
raw, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, fmt.Errorf("base64 decode %w: %s", err, data)
}
// 初始化ViewModel
vm, err := NewViewModel()
if err != nil {
//log.Fatalf("初始化失败: %v", err)
//}
//// 初始化ViewModel
//vm, err := NewViewModel(pubKeyBase64)
//if err != nil {
log.Printf("初始化失败: %v", err)
return nil, fmt.Errorf("base64 decode %w: %s", err, data)
}
reader := bytes.NewReader(raw)
var writer bytes.Buffer
chunk := make([]byte, maxDecryptBlock)
for {
n, err := io.ReadFull(reader, chunk)
if err != nil && errors.Is(err, io.ErrUnexpectedEOF) {
return nil, fmt.Errorf("read decrypted data: %w", err)
}
if n == 0 {
break
}
pubKey := vm.publicKey
decryptChunk(chunk, &writer, pubKey)
}
output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n")
if bytes.Count(output, []byte("\x00")) > 0 {
after := bytes.ReplaceAll(output, []byte("\x00"), []byte{})
log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after)
output = after
}
return output, nil
}
func decryptChunk(chunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) {
// Decrypt each signature chunk
ciphertextInt := new(big.Int)
ciphertextInt.SetBytes(chunk)
decryptedPaddedInt := doDecrypt(new(big.Int), pubKey, ciphertextInt)
// Remove padding
decryptedPaddedBytes := make([]byte, pubKey.Size())
decryptedPaddedInt.FillBytes(decryptedPaddedBytes)
start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00
decryptedBytes := decryptedPaddedBytes[start:]
// Write decrypted signature chunk
writer.Write(decryptedBytes)
}
func doDecrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
// Textbook RSA
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
// ViewModel 处理业务逻辑的视图模型
type ViewModel struct {
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
}
// NewViewModel 初始化视图模型
func NewViewModel() (*ViewModel, error) {
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem")
if err != nil {
fmt.Println(err)
}
fmt.Printf("pubKeyBytes: %s", pubKeyBytes)
block, _ := pem.Decode(pubKeyBytes)
if block != nil {
pubKeyBytes = block.Bytes
}
fmt.Printf("pubKeyBytes: %s", fmt.Sprint(pubKeyBytes))
pubKey, err := x509.ParsePKIXPublicKey(pubKeyBytes)
if err != nil {
return nil, fmt.Errorf("解析公钥失败: %w", err)
}
rsaPubKey, ok := pubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("无效的RSA公钥类型1")
}
priKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/pkcs8_private.pem")
if err != nil {
fmt.Println(err)
}
fmt.Printf("priKeyBytes: %s", priKeyBytes)
block1, _ := pem.Decode(priKeyBytes)
if block1 != nil {
priKeyBytes = block1.Bytes
}
fmt.Printf("priKeyBytes: %s", fmt.Sprint(priKeyBytes))
priKey, err := x509.ParsePKCS8PrivateKey(priKeyBytes)
if err != nil {
return nil, fmt.Errorf("解析私钥失败: %w", err)
}
rsaPriKey, ok := priKey.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("无效的RSA私钥类型2")
}
return &ViewModel{publicKey: rsaPubKey, privateKey: rsaPriKey}, nil
}
// EncryptDeviceInfo 加密设备信息
func (vm *ViewModel) EncryptDeviceInfo(deviceInfo map[string]string) (string, error) {
jsonData, err := json.Marshal(deviceInfo)
if err != nil {
return "", fmt.Errorf("JSON序列化失败: %w", err)
}
plaintext := string(jsonData)
maxBlockSize := vm.publicKey.Size() - 11 // PKCS#1 v1.5填充最大块大小
var encryptedBlocks [][]byte
for i := 0; i < len(plaintext); i += maxBlockSize {
end := i + maxBlockSize
if end > len(plaintext) {
end = len(plaintext)
}
block := []byte(plaintext[i:end])
encryptedBlock, err := rsa.EncryptPKCS1v15(rand.Reader, vm.publicKey, block)
if err != nil {
return "", fmt.Errorf("RSA加密失败: %w", err)
}
encryptedBlocks = append(encryptedBlocks, encryptedBlock)
}
return base64.StdEncoding.EncodeToString(bytesJoin(encryptedBlocks)), nil
}
// DecryptResponse 解密响应数据
func (vm *ViewModel) DecryptResponse(ciphertextBase64 string) (string, error) {
ciphertextBytes, err := base64.StdEncoding.DecodeString(ciphertextBase64)
if err != nil {
return "", fmt.Errorf("响应数据Base64解码失败: %w", err)
}
maxBlockSize := vm.privateKey.Size()
var decryptedBlocks [][]byte
for i := 0; i < len(ciphertextBytes); i += maxBlockSize {
end := i + maxBlockSize
if end > len(ciphertextBytes) {
end = len(ciphertextBytes)
}
block := ciphertextBytes[i:end]
decryptedBlock, err := rsa.DecryptPKCS1v15(rand.Reader, vm.privateKey, block)
if err != nil {
return "", fmt.Errorf("RSA解密失败: %w", err)
}
decryptedBlocks = append(decryptedBlocks, decryptedBlock)
}
return string(bytesJoin(decryptedBlocks)), nil
}
// 辅助函数:合并字节切片
func bytesJoin(s [][]byte) []byte {
var totalLen int
for _, b := range s {
totalLen += len(b)
}
res := make([]byte, totalLen)
for i, b := range s {
copy(res[i:], b)
}
return res
}
func EncryptDeviceInfo() string {
// 设备公共信息
deviceInfo := map[string]string{
"bootTimeInSec": "1595643553",
"countryCode": "CN",
"language": "zh-Hans-CN",
"deviceName": "e910dddb2748c36b47fcde5dd720eec1",
"systemVersion": "14.0",
"machine": "iPhone10,3",
"memory": "3955589120",
"disk": "63900340224",
"sysFileTime": "1595214620.383940",
"model": "D22AP",
"timeZone": "28800",
"deviceInitTime": "1632467920.301150749",
}
// 初始化ViewModel
vm, err := NewViewModel()
if err != nil {
log.Printf("初始化失败: %v", err)
return ""
}
// 加密设备信息
encryptedDeviceInfo, err := vm.EncryptDeviceInfo(deviceInfo)
if err != nil {
log.Printf("设备信息加密失败: %v", err)
return ""
}
fmt.Printf("加密设备信息: %s\n", encryptedDeviceInfo)
// 模拟响应解密(使用加密结果模拟响应数据)
//responseData := encryptedDeviceInfo // 实际应从接口获取encrypted_device_info字段
return encryptedDeviceInfo
}
func main() {
// 设备公共信息
deviceInfo := map[string]string{
"bootTimeInSec": "1595643553",
"countryCode": "CN",
"language": "zh-Hans-CN",
"deviceName": "e910dddb2748c36b47fcde5dd720eec1",
"systemVersion": "14.0",
"machine": "iPhone10,3",
"memory": "3955589120",
"disk": "63900340224",
"sysFileTime": "1595214620.383940",
"model": "D22AP",
"timeZone": "28800",
"deviceInitTime": "1632467920.301150749",
}
// 替换为实际公钥(需去除换行符)
pubKeyBase64 := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCk2GwklLJO0m4Z5PffSSRlv7jNkQhFyoESukIu2duXN9YaC9G7SCQQnyHYs1Si/W4z/u5a4OXBE5+jZ9W9zmc1wfVelf2vnzTfKABA6AJhlsUXs2UjPQrxNRCgu4rALQ2TlbobqqLpIWtm5rqboXs3yJpRfgaLlJvAdihxx2XYQIDAQAB"
// 初始化ViewModel
//vm, err := NewViewModel()
//if err != nil {
// log.Fatalf("初始化失败: %v", err)
//}
//
//// 加密设备信息
//encryptedDeviceInfo, err := vm.EncryptDeviceInfo(deviceInfo)
//if err != nil {
// log.Fatalf("设备信息加密失败: %v", err)
//}
//fmt.Printf("加密设备信息: %s\n", encryptedDeviceInfo)
//
//// 模拟响应解密(使用加密结果模拟响应数据)
//responseData := encryptedDeviceInfo // 实际应从接口获取encrypted_device_info字段
////decrypt(responseData) decrypt(responseData) //
//// 解密响应数据
//decryptedData, err := vm.DecryptResponse(responseData)
//if err != nil {
// log.Fatalf("响应解密失败: %v", err)
//}
//fmt.Printf("解密后数据: %s\n", decryptedData)
//
//// 解析JSON数组(示例)
//var caidsArray []interface{}
//if err := json.Unmarshal([]byte(decryptedData), &caidsArray); err != nil {
// log.Fatalf("JSON解析失败: %v", err)
//}
//fmt.Printf("CAIDs数组: %+v\n", caidsArray)
//}
// 公钥字符串,注意需要剔除换行符
PUBK := pubKeyBase64 // 分配的API接入的公钥字符串
// 序列化设备信息为JSON
jsonBytes, err := json.Marshal(deviceInfo)
if err != nil {
fmt.Printf("JSON序列化错误: %v\n", err)
return
}
jsonStr := string(jsonBytes)
decrypt(jsonStr)
fmt.Printf("PUBK: %s\n", PUBK)
//// 加密设备信息
//encryptedDeviceInfo, err := encryptWithPublicKey(jsonStr, PUBK)
//if err != nil {
// fmt.Printf("加密错误: %v\n", err)
// return
//}
//
//fmt.Printf("加密后的设备信息: %s\n", encryptedDeviceInfo)
//// 将encryptedDeviceInfo填入请求中的encrypted_device_info字段
//
//// 解密响应数据示例
//// 假设从响应中获取的data字段值
//responseData := ""
//decryptedData, err := decryptWithPrivateKey(responseData, PUBK)
//if err != nil {
// fmt.Printf("解密错误: %v\n", err)
// return
//}
//
//fmt.Printf("解密后的响应数据: %s\n", decryptedData)
//// 解析为JSON数组
//var caidsArray []interface{}
//if err := json.Unmarshal([]byte(decryptedData), &caidsArray); err != nil {
// fmt.Printf("JSON解析错误: %v\n", err)
// return
//}
//fmt.Printf("解析后的CAIDS数组: %v\n", caidsArray)
}
// 使用公钥加密数据
func encryptWithPublicKey(data string, pubKeyStr string) (string, error) {
// 解码Base64格式的公钥
pubKeyBytes, err := base64.StdEncoding.DecodeString(pubKeyStr)
if err != nil {
return "", fmt.Errorf("公钥Base64解码错误: %v", err)
}
// 解析公钥
publicKey, err := x509.ParsePKIXPublicKey(pubKeyBytes)
if err != nil {
return "", fmt.Errorf("公钥解析错误: %v", err)
}
// 断言为RSA公钥
rsaPubKey, ok := publicKey.(*rsa.PublicKey)
if !ok {
return "", errors.New("不是RSA公钥")
}
// 计算最大加密块大小
maxEncryptBlock := rsaPubKey.Size() - 42 // PKCS#1 OAEP加密需要预留42字节
dataBytes := []byte(data)
dataLen := len(dataBytes)
var encryptedBytes []byte
// 分段加密
for i := 0; i < dataLen; i += maxEncryptBlock {
end := i + maxEncryptBlock
if end > dataLen {
end = dataLen
}
// 加密当前块
encryptedBlock, err := rsa.EncryptOAEP(
nil,
rand.Reader,
rsaPubKey,
dataBytes[i:end],
nil,
)
if err != nil {
return "", fmt.Errorf("加密错误: %v", err)
}
encryptedBytes = append(encryptedBytes, encryptedBlock...)
}
// Base64编码加密结果
return base64.StdEncoding.EncodeToString(encryptedBytes), nil
}
// 使用私钥解密数据(完整修正版函数)
func decryptWithPrivateKey(encryptedData string, privKeyStr string) (string, error) {
// 解码Base64格式的加密数据
encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedData)
if err != nil {
return "", fmt.Errorf("加密数据Base64解码错误: %v", err)
}
// 解码Base64格式的私钥
privKeyBytes, err := base64.StdEncoding.DecodeString(privKeyStr)
if err != nil {
return "", fmt.Errorf("私钥Base64解码错误: %v", err)
}
// 解析私钥
privateKey, err := x509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
return "", fmt.Errorf("私钥解析错误: %v", err)
}
// 断言为RSA私钥
rsaPrivKey, ok := privateKey.(*rsa.PrivateKey)
if !ok {
return "", errors.New("不是RSA私钥")
}
// 计算最大解密块大小
maxDecryptBlock := rsaPrivKey.Size()
encryptedLen := len(encryptedBytes)
var decryptedBytes []byte
// 分段解密
for i := 0; i < encryptedLen; i += maxDecryptBlock {
end := i + maxDecryptBlock
if end > encryptedLen {
end = encryptedLen
}
// 使用私钥进行解密(这是RSA的标准做法)
decryptedBlock, err := rsa.DecryptOAEP(
nil,
rand.Reader,
rsaPrivKey,
encryptedBytes[i:end],
nil,
)
if err != nil {
return "", fmt.Errorf("解密错误: %v", err)
}
decryptedBytes = append(decryptedBytes, decryptedBlock...)
}
return string(decryptedBytes), nil
}
Loading…
Cancel
Save