Golang-aes encryption (CBC mode, PKCS7 padding)

Source: Internet
Author: User
Tags pkcs7

Symmetric encryption algorithms, that is, encryption and decryption using the same cryptographic key encryption and decryption algorithm.
Block cipher is a class of encryption and decryption algorithms that can handle only a block of data of a specific length at a time.
At present, the symmetric encryption Algorithm DES, 3DES, AES belong to the block cipher.


Background



Golang does not provide a ready-made AES encryption function like PHP, but there are crypto in the standard library, using AES inside to encapsulate an encryption function, but understand the whole process and principle of decryption



AES Encryption detailed



1. Refer to AES encryption in article Golang



2. Here is the CBC mode in AES encryption, block encryption needs to be divided into integers equal to the length of the message block is continuously encrypted (serial), the packet length is fixed 128 bits, but the length of the key can use 128 bits, 192 bits or 256 bits (this refers to a bit), that is, the key 16, 24,32 length corresponds to AES-128, AES-192, AES-256.



3. The initial vector requires random, but does not require secrecy.



Code



Their own research code is clear, according to Golang Standard library AES Instance code, and then refer to the online PKCS7 fill, and finally base64 encoding (because some characters are not visible after encryption). Finally encrypt and Dncrypt two is AES plus decryption (CBC mode, PKCS7 fill) After the encapsulated function, the number of key Bits limited 16,24,32 (note that the key no matter how much, blocksize are fixed 16)


Package encrypt

Import (
   "bytes"
   "crypto/aes"
   "io"
   "crypto/rand"
   "crypto/cipher"
   "encoding/base64"
)

/*CBC encryption Follow the example code of the golang standard library
But there is no padding inside, so make up
*/

/ / Use PKCS7 to fill, IOS is also 7
Func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
   Padding := blockSize - len(ciphertext) % blockSize
   Padtext := bytes.Repeat([]byte{byte(padding)}, padding)
   Return append(ciphertext, padtext...)
}

Func PKCS7UnPadding(origData []byte) []byte {
   Length := len(origData)
   Unpadding := int(origData[length-1])
   Return origData[:(length - unpadding)]
}

//aes encryption, filling the 16 bits of the key key, 24, 32 respectively corresponding to AES-128, AES-192, or AES-256.
Func AesCBCEncrypt(rawData,key []byte) ([]byte, error) {
   Block, err := aes.NewCipher(key)
   If err != nil {
       Panic(err)
   }

   //fill the original
   blockSize := block.BlockSize()
   rawData = PKCS7Padding(rawData, blockSize)
   / / Initial vector IV must be unique, but does not need to be kept secret
   cipherText := make([]byte,blockSize+len(rawData))
   //block size 16
   Iv := cipherText[:blockSize]
   If _, err := io.ReadFull(rand.Reader,iv); err != nil {
       Panic(err)
   }

   //block size and initial vector size must be the same
   Mode := cipher.NewCBCEncrypter(block,iv)
   mode.CryptBlocks(cipherText[blockSize:], rawData)

   Return cipherText, nil
}

Func AesCBCDncrypt(encryptData, key []byte) ([]byte,error) {
   Block, err := aes.NewCipher(key)
   If err != nil {
       Panic(err)
   }

   blockSize := block.BlockSize()

   If len(encryptData) < blockSize {
       Panic("ciphertext too short")
   }
   Iv := encryptData[:blockSize]
   encryptData = encryptData[blockSize:]

   // CBC mode always works in whole blocks.
   If len(encryptData)%blockSize != 0 {
       Panic("ciphertext is not a multiple of the block size")
   }

   Mode := cipher.NewCBCDecrypter(block, iv)

   // CryptBlocks can work in-place if the two arguments are the same.
   mode.CryptBlocks(encryptData, encryptData)
   / / Unfill
   encryptData = PKCS7UnPadding(encryptData)
   Return encryptData,nil
}


Func Encrypt(rawData,key []byte) (string,error) {
   Data, err:= AesCBCEncrypt(rawData,key)
   If err != nil {
       Return "", err
   }
   Return base64.StdEncoding.EncodeToString(data),nil
}

Func Dncrypt(rawData string,key []byte) (string,error) {
   Data,err := base64.StdEncoding.DecodeString(rawData)
   If err != nil {
       Return "", err
   }
   dnData,err := AesCBCDncrypt(data,key)
   If err != nil {
       Return "", err
   }
   Return string(dnData),nil
} 


Reference:


    1. AES Encryption in Golang
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.