golang blowfish ecb pkcs5 加解密
package main import ( "bytes" "crypto/cipher" "encoding/base64" "errors" "fmt" "strconv" "golang.org/x/crypto/blowfish" ) func main() { key := "PPpn7ugdcTa4DTUdqSkxSeR7gTsv93Q576ug8QMdeLbVFPte" price := "29.20" enc, err := BlowfishECBEncrypt(price, key) if err != nil { fmt.Println("-------err: ", err) } encodeStr := base64.URLEncoding.EncodeToString(enc) fmt.Println("encode=", encodeStr) enc, err = base64.URLEncoding.DecodeString(encodeStr) if err != nil { fmt.Println("-------err: ", err) } price2, err := BlowfishECBDecrypt(enc, []byte(key)) if err != nil { fmt.Println("--------err decode=", err) } fmt.Println("decode=", string(price2)) price1, err := strconv.ParseFloat(string(price2), 64) if err != nil { fmt.Println("parse float is failed, err:", err) } fmt.Println("------------price1=", price1) } func BlowfishECBEncrypt(src, key string) ([]byte, error) { block, err := blowfish.NewCipher([]byte(key)) if err != nil { return nil, err } if src == "" { return nil, errors.New("plain content empty") } ecb := NewECBEncrypter(block) content := []byte(src) content = PKCS5Padding(content, block.BlockSize()) crypted := make([]byte, len(content)) ecb.CryptBlocks(crypted, content) return crypted, nil } func BlowfishECBDecrypt(crypted, key []byte) ([]byte, error) { block, err := blowfish.NewCipher([]byte(key)) if err != nil { return nil, err } blockMode := NewECBDecrypter(block) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS5UnPadding(origData) return origData, nil } type ECB struct { b cipher.Block blockSize int } func NewECB(b cipher.Block) *ECB { return &ECB{ b: b, blockSize: b.BlockSize(), } } type ECBEncrypter ECB // NewECBEncrypter returns a BlockMode which encrypts in electronic code book // mode, using the given Block. func NewECBEncrypter(b cipher.Block) cipher.BlockMode { return (*ECBEncrypter)(NewECB(b)) } func (x *ECBEncrypter) BlockSize() int { return x.blockSize } func (x *ECBEncrypter) 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:] } } type ECBDecrypter ECB // NewECBDecrypter returns a BlockMode which decrypts in electronic code book // mode, using the given Block. func NewECBDecrypter(b cipher.Block) cipher.BlockMode { return (*ECBDecrypter)(NewECB(b)) } func (x *ECBDecrypter) BlockSize() int { return x.blockSize } func (x *ECBDecrypter) 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:] } } // 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 次 unpadding := int(origData[length-1]) return origData[:(length - unpadding)] }