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: 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 }