gitee.com/h79/goutils@v1.22.10/common/algorithm/pkcs7.go (about) 1 package algorithm 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 "crypto/rand" 7 "encoding/base64" 8 "fmt" 9 "io" 10 ) 11 12 // PKCS7 for aes 13 type PKCS7 struct { 14 } 15 16 func NewPKCS7() *PKCS7 { 17 return &PKCS7{} 18 } 19 20 func (pk *PKCS7) padding(ciphertext []byte, blockSize int) []byte { 21 return pkcs7Padding(ciphertext, blockSize) 22 } 23 24 func (pk *PKCS7) unPadding(data []byte) []byte { 25 return pkcs7UnPadding(data) 26 } 27 28 // aes加密,填充秘钥key的16位,24,32分别对应AES-128, AES-192, or AES-256. 29 func (pk *PKCS7) aesCbcEncrypt(raw, key []byte, iv []byte) ([]byte, error) { 30 block, err := aes.NewCipher(key) 31 if err != nil { 32 return nil, err 33 } 34 35 //填充原文 36 blockSize := block.BlockSize() 37 raw = pk.padding(raw, blockSize) 38 39 //初始向量IV必须是唯一,但不需要保密 40 var cipherText []byte 41 if len(iv) < blockSize { 42 //block大小 16 43 cipherText = make([]byte, blockSize+len(raw)) 44 iv = cipherText[:blockSize] 45 if _, er := io.ReadFull(rand.Reader, iv); er != nil { 46 return nil, er 47 } 48 } else { 49 cipherText = make([]byte, len(raw)) 50 blockSize = 0 51 } 52 //block大小和初始向量大小一定要一致 53 mode := cipher.NewCBCEncrypter(block, iv) 54 mode.CryptBlocks(cipherText[blockSize:], raw) 55 56 return cipherText, nil 57 } 58 59 func (pk *PKCS7) aesCbcDecrypt(encryptData, aesKey []byte, iv []byte) ([]byte, error) { 60 block, err := aes.NewCipher(aesKey) 61 if err != nil { 62 return nil, err 63 } 64 65 blockSize := block.BlockSize() 66 67 if len(encryptData) < blockSize { 68 return nil, fmt.Errorf("ciphertext too short") 69 } 70 71 if len(iv) == 0 { 72 iv = encryptData[:blockSize] 73 encryptData = encryptData[blockSize:] 74 } 75 // CBC mode always works in whole blocks. 76 if len(encryptData)%blockSize != 0 { 77 return nil, fmt.Errorf("ciphertext is not a multiple of the block size") 78 } 79 80 mode := cipher.NewCBCDecrypter(block, iv) 81 82 // CryptBlocks can work in-place if the two arguments are the same. 83 mode.CryptBlocks(encryptData, encryptData) 84 85 //解填充 86 return pk.unPadding(encryptData), nil 87 } 88 89 // Encrypt PKCS interface 90 func (pk *PKCS7) Encrypt(raw, key []byte) (string, error) { 91 return pk.EncryptIv(raw, key, nil) 92 } 93 94 // EncryptIv 95 // 带IV 96 func (pk *PKCS7) EncryptIv(raw, aesKey []byte, iv []byte) (string, error) { 97 data, err := pk.aesCbcEncrypt(raw, aesKey, iv) 98 if err != nil { 99 return "", err 100 } 101 return base64.StdEncoding.EncodeToString(data), nil 102 } 103 104 // Decrypt PKCS interface 105 func (pk *PKCS7) Decrypt(raw string, key []byte) ([]byte, error) { 106 return pk.DecryptIv(raw, key, nil) 107 } 108 109 // DecryptIv 110 // 带IV 111 func (pk *PKCS7) DecryptIv(raw string, aesKey []byte, iv []byte) ([]byte, error) { 112 data, err := base64.StdEncoding.DecodeString(raw) 113 if err != nil { 114 return nil, err 115 } 116 return pk.aesCbcDecrypt(data, aesKey, iv) 117 }