func DecryptWxMessage(encryptedBase64, encodingAESKey string) (string, string, error) {
encryptedBase64 = strings.TrimSpace(encryptedBase64)
encryptedBase64 = strings.ReplaceAll(encryptedBase64, "\n", "")
encryptedBase64 = strings.ReplaceAll(encryptedBase64, "\r", "")
aesKey, err := base64.StdEncoding.DecodeString(encodingAESKey + "=")
if err != nil {
return "", "", fmt.Errorf("decode AES key failed: %w", err)
}
if len(aesKey) != 32 {
return "", "", fmt.Errorf("AES key length invalid, got %d, want 32", len(aesKey))
}
cipherData, err := base64.StdEncoding.DecodeString(encryptedBase64)
if err != nil {
return "", "", fmt.Errorf("decode base64 cipher failed: %w", err)
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return "", "", fmt.Errorf("new AES cipher failed: %w", err)
}
if len(cipherData)%block.BlockSize() != 0 {
return "", "", fmt.Errorf("ciphertext length (%d) is not multiple of block size (%d)", len(cipherData), block.BlockSize())
}
iv := aesKey[:block.BlockSize()]
mode := cipher.NewCBCDecrypter(block, iv)
plainData := make([]byte, len(cipherData))
mode.CryptBlocks(plainData, cipherData)
plainData, err = PKCS7UnpaddingOfficial(plainData)
if err != nil {
return "", "", fmt.Errorf("PKCS7 unpadding failed: %w", err)
}
if len(plainData) < 20 {
return "", "", fmt.Errorf("plaintext too short: %d bytes", len(plainData))
}
msgLen := binary.BigEndian.Uint32(plainData[16:20])
if int(20+msgLen) > len(plainData) {
head20 := plainData[:20]
return "", "", fmt.Errorf("invalid msg length: %d, plaintext len: %d, head20=%x", msgLen, len(plainData), head20)
}
jsonMsg := plainData[20 : 20+msgLen]
appId := string(plainData[20+msgLen:])
return string(jsonMsg), appId, nil
}
微信小店的