|
|
|
@ -12,169 +12,35 @@ import ( |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"io" |
|
|
|
"io" |
|
|
|
"io/ioutil" |
|
|
|
"io/ioutil" |
|
|
|
"log" |
|
|
|
|
|
|
|
"math/big" |
|
|
|
"math/big" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const maxDecryptBlock = 128 |
|
|
|
const maxDecryptBlock = 128 |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
/* |
|
|
|
//func Decrypt(data string) ([]byte, error) {
|
|
|
|
url := "https://caid.china-caa.org/v1.0/get" |
|
|
|
// raw, err := base64.StdEncoding.DecodeString(data)
|
|
|
|
data := map[string]interface{}{"dev_id": "10702", "encrypted_device_info": caid.EncryptDeviceInfo()} |
|
|
|
// if err != nil {
|
|
|
|
tmp, err := SendCaidMsg(ctx, url, data) |
|
|
|
// 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 { |
|
|
|
if err != nil { |
|
|
|
return nil, fmt.Errorf("解析公钥失败: %w", err) |
|
|
|
fmt.Println("SendCaidMsg err:", err) |
|
|
|
} |
|
|
|
return |
|
|
|
rsaPubKey, ok := pubKey.(*rsa.PublicKey) |
|
|
|
|
|
|
|
if !ok { |
|
|
|
|
|
|
|
return nil, errors.New("无效的RSA公钥类型1") |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return &ViewModel{publicKey: rsaPubKey}, nil |
|
|
|
resJson, err := gjson.DecodeToJson(tmp) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// EncryptDeviceInfo 加密设备信息
|
|
|
|
|
|
|
|
func (vm *ViewModel) EncryptDeviceInfo(deviceInfo map[string]string) (string, error) { |
|
|
|
|
|
|
|
jsonData, err := json.Marshal(deviceInfo) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return "", fmt.Errorf("JSON序列化失败: %w", err) |
|
|
|
fmt.Println("SendCaidMsg DecodeToJson err:", err) |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
plaintext := string(jsonData) |
|
|
|
if resJson != nil && resJson.Get("code").Int() != 0 { |
|
|
|
maxBlockSize := vm.publicKey.Size() - 11 // PKCS#1 v1.5填充最大块大小
|
|
|
|
fmt.Println("SendCaidMsg err:", resJson.Get("message").String()) |
|
|
|
fmt.Println("EncryptDeviceInfo", maxBlockSize, len(jsonData), len(plaintext)) |
|
|
|
return |
|
|
|
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 |
|
|
|
req.Caid = resJson.Get("data").String() |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
// 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 { |
|
|
|
func EncryptDeviceInfo() string { |
|
|
|
// 设备公共信息
|
|
|
|
// 设备公共信息
|
|
|
|
deviceInfo := map[string]string{ |
|
|
|
deviceInfo := map[string]string{ |
|
|
|
@ -192,76 +58,15 @@ func EncryptDeviceInfo() string { |
|
|
|
"deviceInitTime": "1632467920.301150749", |
|
|
|
"deviceInitTime": "1632467920.301150749", |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 初始化ViewModel
|
|
|
|
encryptedDeviceInfo, err := Encrypt(deviceInfo) |
|
|
|
vm, err := NewViewModel() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
log.Printf("初始化失败: %v", err) |
|
|
|
fmt.Println(err) |
|
|
|
return "" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 加密设备信息
|
|
|
|
|
|
|
|
encryptedDeviceInfo, err := vm.EncryptDeviceInfo(deviceInfo) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
log.Printf("设备信息加密失败: %v", err) |
|
|
|
|
|
|
|
return "" |
|
|
|
return "" |
|
|
|
} |
|
|
|
} |
|
|
|
fmt.Printf("加密设备信息: %s\n", encryptedDeviceInfo) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟响应解密(使用加密结果模拟响应数据)
|
|
|
|
// 模拟响应解密(使用加密结果模拟响应数据)
|
|
|
|
//responseData := encryptedDeviceInfo // 实际应从接口获取encrypted_device_info字段
|
|
|
|
|
|
|
|
return encryptedDeviceInfo |
|
|
|
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) { |
|
|
|
func Decrypt(data string) ([]byte, error) { |
|
|
|
raw, err := base64.StdEncoding.DecodeString(data) |
|
|
|
raw, err := base64.StdEncoding.DecodeString(data) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
@ -274,13 +79,12 @@ func Decrypt(data string) ([]byte, error) { |
|
|
|
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem") |
|
|
|
pubKeyBytes, err := ioutil.ReadFile("manifest/config/dev_10702/public_for_api.pem") |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
fmt.Println(err) |
|
|
|
fmt.Println(err) |
|
|
|
|
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
fmt.Printf("pubKeyBytes: %s\n", pubKeyBytes) |
|
|
|
|
|
|
|
block, _ := pem.Decode(pubKeyBytes) |
|
|
|
block, _ := pem.Decode(pubKeyBytes) |
|
|
|
if block != nil { |
|
|
|
if block != nil { |
|
|
|
pubKeyBytes = block.Bytes |
|
|
|
pubKeyBytes = block.Bytes |
|
|
|
} |
|
|
|
} |
|
|
|
fmt.Printf("pubKeyBytes: %s\n", fmt.Sprint(pubKeyBytes)) |
|
|
|
|
|
|
|
pubKey, err := x509.ParsePKIXPublicKey(pubKeyBytes) |
|
|
|
pubKey, err := x509.ParsePKIXPublicKey(pubKeyBytes) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, fmt.Errorf("解析公钥失败: %w", err) |
|
|
|
return nil, fmt.Errorf("解析公钥失败: %w", err) |
|
|
|
@ -302,7 +106,7 @@ func Decrypt(data string) ([]byte, error) { |
|
|
|
output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n") |
|
|
|
output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n") |
|
|
|
if bytes.Count(output, []byte("\x00")) > 0 { |
|
|
|
if bytes.Count(output, []byte("\x00")) > 0 { |
|
|
|
after := bytes.ReplaceAll(output, []byte("\x00"), []byte{}) |
|
|
|
after := bytes.ReplaceAll(output, []byte("\x00"), []byte{}) |
|
|
|
log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after) |
|
|
|
//log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after)
|
|
|
|
output = after |
|
|
|
output = after |
|
|
|
} |
|
|
|
} |
|
|
|
fmt.Printf(" output: %s\n", string(output)) |
|
|
|
fmt.Printf(" output: %s\n", string(output)) |
|
|
|
@ -329,3 +133,59 @@ func doDecrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int { |
|
|
|
c.Exp(m, e, pub.N) |
|
|
|
c.Exp(m, e, pub.N) |
|
|
|
return c |
|
|
|
return c |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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 { |
|
|
|
|
|
|
|
fmt.Printf("publicKey : %d\n ", publicKey.Size()) |
|
|
|
|
|
|
|
return publicKey |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func Encrypt(data map[string]string) (string, error) { |
|
|
|
|
|
|
|
jsonBytes, err := json.Marshal(data) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Printf("JSON序列化错误: %v\n", err) |
|
|
|
|
|
|
|
return "", fmt.Errorf("JSON序列化错误: %v\n", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pubKey := ImportSPKIPublicKeyPEM() |
|
|
|
|
|
|
|
fmt.Printf("data: len: %d\n pubkey: %v\n", len(data), pubKey) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 计算RSA最大加密块大小(PKCS#1 v1.5填充需要11字节)
|
|
|
|
|
|
|
|
keySize := pubKey.Size() // 密钥字节长度(如2048位密钥为256字节)
|
|
|
|
|
|
|
|
maxEncryptBlock := keySize - 11 // 最大单次加密数据长度(256-11=245字节)
|
|
|
|
|
|
|
|
if maxEncryptBlock <= 0 { |
|
|
|
|
|
|
|
return "", errors.New("无效的RSA公钥长度(必须≥11字节)") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
plaintext := jsonBytes |
|
|
|
|
|
|
|
// 3. 分块加密
|
|
|
|
|
|
|
|
var encryptedBlocks [][]byte |
|
|
|
|
|
|
|
for offset := 0; offset < len(plaintext); offset += maxEncryptBlock { |
|
|
|
|
|
|
|
end := offset + maxEncryptBlock |
|
|
|
|
|
|
|
if end > len(plaintext) { |
|
|
|
|
|
|
|
end = len(plaintext) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
block := plaintext[offset:end] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 执行RSA加密(使用公钥指数e)
|
|
|
|
|
|
|
|
encryptedBlock, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, block) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return "", fmt.Errorf("第%d字节块加密失败: %w", offset, err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
encryptedBlocks = append(encryptedBlocks, encryptedBlock) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 拼接所有加密块并进行Base64编码
|
|
|
|
|
|
|
|
encryptedBytes := bytes.Join(encryptedBlocks, nil) |
|
|
|
|
|
|
|
// 4. 拼接所有加密块并进行Base64编码
|
|
|
|
|
|
|
|
return base64.StdEncoding.EncodeToString(encryptedBytes), nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|