123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package crypto
- import (
- stdcrypto "crypto"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/base64"
- "encoding/pem"
- "net/url"
- "sort"
- "strings"
- "github.com/pkg/errors"
- )
- // Alipay alipay cryptor
- type Alipay struct {
- aliPub []byte
- biliPriv []byte
- }
- // NewAlipay is.
- func NewAlipay(aliPub, biliPriv string) (a *Alipay) {
- return &Alipay{
- aliPub: ParsePublicKey(aliPub),
- biliPriv: ParsePrivateKey(biliPriv),
- }
- }
- func (e *Alipay) splitData(originalData []byte, packageSize int) (r [][]byte) {
- var src = make([]byte, len(originalData))
- copy(src, originalData)
- r = make([][]byte, 0)
- if len(src) <= packageSize {
- return append(r, src)
- }
- for len(src) > 0 {
- var p = src[:packageSize]
- r = append(r, p)
- src = src[packageSize:]
- if len(src) <= packageSize {
- r = append(r, src)
- break
- }
- }
- return r
- }
- // EncryptParam rsa encrypt.
- func (e *Alipay) EncryptParam(p url.Values) (ep string, err error) {
- var (
- pubInterface interface{}
- pub *rsa.PublicKey
- data []byte
- block *pem.Block
- )
- block, _ = pem.Decode(e.aliPub)
- if block == nil {
- err = errors.New("private key error")
- return
- }
- if pubInterface, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
- err = errors.WithStack(err)
- return
- }
- pub = pubInterface.(*rsa.PublicKey)
- var sd = e.splitData([]byte(p.Encode()), pub.N.BitLen()/8-11)
- for _, d := range sd {
- var pd []byte
- if pd, err = rsa.EncryptPKCS1v15(rand.Reader, pub, d); err != nil {
- err = errors.WithStack(err)
- return
- }
- data = append(data, pd...)
- }
- ep = base64.StdEncoding.EncodeToString(data)
- return
- }
- // SignParam sign alipay param
- func (e *Alipay) SignParam(p url.Values) (sign string, err error) {
- if p == nil {
- p = make(url.Values)
- }
- var pList = make([]string, 0)
- for key := range p {
- var value = strings.TrimSpace(p.Get(key))
- if len(value) > 0 {
- pList = append(pList, key+"="+value)
- }
- }
- sort.Strings(pList)
- var src = strings.Join(pList, "&")
- var h = stdcrypto.SHA256.New()
- if _, err = h.Write([]byte(src)); err != nil {
- err = errors.WithStack(err)
- return
- }
- var (
- hashed = h.Sum(nil)
- pri *rsa.PrivateKey
- data []byte
- block *pem.Block
- )
- block, _ = pem.Decode(e.biliPriv)
- if block == nil {
- err = errors.New("private key error")
- return
- }
- if pri, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
- err = errors.WithStack(err)
- return
- }
- if data, err = rsa.SignPKCS1v15(rand.Reader, pri, stdcrypto.SHA256, hashed); err != nil {
- err = errors.WithStack(err)
- return
- }
- sign = base64.StdEncoding.EncodeToString(data)
- return
- }
|