package transferv3 import ( "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/json" "fmt" ) // DecryptResource 解密回调 resource(文档:AEAD_AES_256_GCM,密钥 APIv3 32 字节,密文=实际密文+16 字节 tag) func DecryptResource(ciphertextBase64, nonce, associatedData string, apiV3Key []byte) ([]byte, error) { if len(apiV3Key) != 32 { return nil, fmt.Errorf("apiV3 key must be 32 bytes, got %d", len(apiV3Key)) } raw, err := base64.StdEncoding.DecodeString(ciphertextBase64) if err != nil { return nil, fmt.Errorf("base64 decode: %w", err) } if len(raw) < 16 { return nil, fmt.Errorf("ciphertext too short") } tag := raw[len(raw)-16:] ctext := raw[:len(raw)-16] block, err := aes.NewCipher(apiV3Key) if err != nil { return nil, err } aead, err := cipher.NewGCM(block) if err != nil { return nil, err } plain, err := aead.Open(nil, []byte(nonce), append(ctext, tag...), []byte(associatedData)) if err != nil { return nil, fmt.Errorf("aes-gcm decrypt: %w", err) } return plain, nil } // DecryptResourceJSON 解密并解析为 JSON 对象(回调解密后的 resource) func DecryptResourceJSON(ciphertextBase64, nonce, associatedData string, apiV3Key []byte) (map[string]interface{}, error) { plain, err := DecryptResource(ciphertextBase64, nonce, associatedData, apiV3Key) if err != nil { return nil, err } var out map[string]interface{} if err := json.Unmarshal(plain, &out); err != nil { return nil, err } return out, nil }