53 lines
1.5 KiB
Go
53 lines
1.5 KiB
Go
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
|
||
}
|