1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-07 06:02:26 +08:00

微信支付 - 退款通知 (#359)

* 🆕 发起退款 - 添加notify_url参数

* 🆕 退款通知
This commit is contained in:
LouGaZen
2021-02-07 09:49:43 +08:00
committed by GitHub
parent e5f0d5eab7
commit d5a67eaf29
4 changed files with 213 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
package util
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
@@ -227,3 +228,105 @@ func ParamSign(p map[string]string, key string) (string, error) {
return CalculateSign(str, signType, key)
}
// ECB provides confidentiality by assigning a fixed ciphertext block to each plaintext block.
// See NIST SP 800-38A, pp 08-09
// reference: https://codereview.appspot.com/7860047/patch/23001/24001
type ecb struct {
b cipher.Block
blockSize int
}
func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
}
// ECBEncryptor -
type ECBEncryptor ecb
// NewECBEncryptor returns a BlockMode which encrypts in electronic code book mode, using the given Block.
func NewECBEncryptor(b cipher.Block) cipher.BlockMode {
return (*ECBEncryptor)(newECB(b))
}
// BlockSize implement BlockMode.BlockSize
func (x *ECBEncryptor) BlockSize() int {
return x.blockSize
}
// CryptBlocks implement BlockMode.CryptBlocks
func (x *ECBEncryptor) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Encrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
// ECBDecryptor -
type ECBDecryptor ecb
// NewECBDecryptor returns a BlockMode which decrypts in electronic code book mode, using the given Block.
func NewECBDecryptor(b cipher.Block) cipher.BlockMode {
return (*ECBDecryptor)(newECB(b))
}
// BlockSize implement BlockMode.BlockSize
func (x *ECBDecryptor) BlockSize() int {
return x.blockSize
}
// CryptBlocks implement BlockMode.CryptBlocks
func (x *ECBDecryptor) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Decrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
// AesECBDecrypt will decrypt data with PKCS5Padding
func AesECBDecrypt(ciphertext []byte, aesKey []byte) ([]byte, error) {
if len(ciphertext) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
// ECB mode always works in whole blocks.
if len(ciphertext)%aes.BlockSize != 0 {
return nil, errors.New("ciphertext is not a multiple of the block size")
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return nil, err
}
NewECBDecryptor(block).CryptBlocks(ciphertext, ciphertext)
return PKCS5UnPadding(ciphertext), nil
}
// PKCS5Padding -
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padText...)
}
// PKCS5UnPadding -
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unPadding := int(origData[length-1])
return origData[:(length - unPadding)]
}