AES Encryption in Golang

Source: Internet
Author: User
Tags hmac
This is a creation in Article, where the information may have evolved or changed.

The Golang standard library for AES encryption is very concise, if not a certain basic knowledge of cryptography, it is easy to confuse.
This article provides a complete overview of the basics of AES encryption and analyzes common invocation instances on the network.


The working mode of block cipher is simple


Main excerpt from Wikipedia: block cipher working mode


Basic concepts


    • In cryptography, the working mode of Block cipher (English: Mode of operation) allows the use of the same block cipher key to encrypt more than one piece of data and ensure its security.
    • The block cipher itself only encrypts a single block of data that is equal to the length of the cipher block, and to encrypt the variable length data, the data must first be divided into separate cipher blocks. In general, the last piece of data also needs to extend the data to a length that fits the cipher block size using the appropriate padding method.
    • A working mode describes the process of encrypting each block of data and often uses additional input values based on a commonly called initialization vector to be randomized to ensure security.
    • Common patterns are ecb,cbc,ofb,cfb,ctr and xts, etc.
    • Encryption mode only guarantees confidentiality , and for integrity or non-tampering, separate message verification codes, such as CBC-MAC, are required. The cryptography Group recognized the need for proprietary methods of guaranteeing integrity, and NIST therefore proposed Hmac,cmac and GMAC.
    • After discovering the difficulty of combining authentication patterns with cryptographic patterns, the cryptography community began to study a single pattern that combines encryption and authentication, which is known as the authentication encryption mode (ae,authenticated encryption), or Authenc. Examples of AE modes include CCM,GCM[11],CWC,EAX,IAPM and OCB.


Initialization vector (IV)



The initialization vector (iv,initialization vector) is a piece of data that is used to randomize encryption in many operating modes, so that different ciphertext can be generated by the same plaintext, the same key, without having to regenerate the key, avoiding the usually rather complex process.



The initialization vector has different security requirements than the key, so IV is usually not confidential, but in most cases, the same IV should not be used two times with the same key. For CBC and CFB, reusing IV causes some information to leak the first plaintext block, and also includes the same prefix in two different messages. For OFB and CTR, reusing IV can lead to total loss of security. In addition, in CBC mode, iv must be unpredictable in encryption, and, in particular, the method of Generation IV used in many implementations, such as SSL2.0, which uses the last cipher of the previous message as the IV of the next message, is unsafe.



Fill


    • Partial mode (ECB and CBC) requires the last block to be populated before encryption
    • The CFB,OFB and CTR modes do not require special handling of messages with lengths that are not integer times the size of the cipher block. Because these patterns are based on the output of the block password and Pingwen to different or work. The last flat block (which may be incomplete) and the first few bytes of the key stream block will produce a cipher block of the same size as the flat block. This feature of stream ciphers allows them to be used in situations where the length of ciphertext and text data is strictly equal, or it can be used to transmit data in a stream and not be easily populated.
    • Example of two fill codes
func PKCS5Padding (ciphertext [] byte, blockSize int) [] byte {
        padding: = blockSize-len (ciphertext)% blockSize // number of padding required
        // As long as it is less than 256, it can be put into a byte. The default blockSize = 16 (that is, 16 * 8 = 128, AES-128 key)
        // fill at least 1 byte, if the original is exactly an integer multiple of blocksize, then fill a blocksize
        padtext: = bytes.Repeat ([] byte (byte (padding)}, padding) // Generate padding text
        return append (ciphertext, padtext ...)
}

func PKCS5UnPadding (origData [] byte) [] byte {
        length: = len (origData)
        unpadding: = int (origData [length-1])
        return origData [:( length-unpadding)]
}

func ZeroPadding (ciphertext [] byte, blockSize int) [] byte {
        padding: = blockSize-len (ciphertext)% blockSize
        padtext: = bytes.Repeat ([] byte {0}, padding) // padding with 0
        return append (ciphertext, padtext ...)
}

func ZeroUnPadding (origData [] byte) [] byte {
        return bytes.TrimFunc (origData,
                func (r rune) bool {
                        return r == rune (0)
                })
} 


Common patterns



ECB (Electronic codebook) mode



Encryption:

Decrypt:

The disadvantage of applying a secret key to each cipher block is that the same block of text is encrypted into the same cipher block, so it cannot hide the data pattern well. In some cases, this approach does not provide strict data confidentiality and is therefore not recommended for use in cryptographic protocols. The following example shows the extent to which the ECB displays the flat text pattern in ciphertext: a bitmap version of the image (left) may be encrypted in the ECB mode, rather than the ECB mode, which usually encrypts it

And because each block is encrypted separately, the protocol itself does not provide data integrity protection, and it is easy to receive the impact of replay attacks.



CBC (Cipher-block chaining) mode



Encryption:

Decrypt:

In CBC mode, each block is first XOR with the previous cipher block before being encrypted. In this approach, each cipher block relies on all the plain blocks in front of it. Also, in order to guarantee the uniqueness of each message, an initialization vector is used in the first block.



CBC is the most commonly used mode of operation. Its main disadvantage is that the encryption process is serial, cannot be parallelized, and the message must be filled to an integer multiple of the block size. One way to solve the latter problem is to steal with ciphertext.



Note that in the case of encryption, the small changes in the text will cause the entire cipher block to change, and in the decryption, a block can be obtained from the two contiguous cipher blocks. Therefore, the decryption process can be parallelized, and decryption, the ciphertext of a change will only cause its corresponding flat text block completely change and the corresponding bit in the next flat block changes, will not affect the content of other plain text.



Golang Standard library AES Instance code



Https://golang.org/src/crypto/cipher/example_test.go
The example includes AES usage in a variety of modes, and we focus on the most common CBC patterns


func ExampleNewCBCEncrypter () {
        key: = [] byte ("example key 1234") // AES-128 (16bytes) or AES-256 (32bytes)
        plaintext: = [] byte ("exampleplaintext") // The original text must be filled to an integer multiple of the blocksize. For the filling method, see https://tools.ietf.org/html/rfc5246#section-6.2.3.2

        if len (plaintext)% aes.BlockSize! = 0 {// Block size is defined in aes.BlockSize
                panic ("plaintext is not a multiple of the block size")
        }

        block, err: = aes.NewCipher (key) // Generate a block for encryption
        if err! = nil {
                panic (err)
        }

        // There are random requirements for the IV, but there is no confidentiality requirement, so the common practice is to include the IV in the encrypted text
        ciphertext: = make ([] byte, aes.BlockSize + len (plaintext))
        // Random a block size as IV
        // When different IVs are used, the same secret key will generate different ciphertexts, which can be understood as an encrypted session
        iv: = ciphertext [: aes.BlockSize]
        if _, err: = io.ReadFull (rand.Reader, iv); err! = nil {
                panic (err)
        }

        mode: = cipher.NewCBCEncrypter (block, iv)
        mode.CryptBlocks (ciphertext [aes.BlockSize:], plaintext)

        // Remember that ciphertext requires authentication (i.e. by using crypto / hmac)

        fmt.Printf ("% x \ n", ciphertext)
}
func ExampleNewCBCDecrypter () {
        key: = [] byte ("example key 1234")
        ciphertext, _: = hex.DecodeString ("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")

        block, err: = aes.NewCipher (key)
        if err! = nil {
                panic (err)
        }

        if len (ciphertext) <aes.BlockSize {
                panic ("ciphertext too short")
        }
        iv: = ciphertext [: aes.BlockSize]
        ciphertext = ciphertext [aes.BlockSize:]

        // CBC mode always works in whole blocks.
        if len (ciphertext)% aes.BlockSize! = 0 {
                panic ("ciphertext is not a multiple of the block size")
        }

        mode: = cipher.NewCBCDecrypter (block, iv)

        // CryptBlocks can be updated in place
        mode.CryptBlocks (ciphertext, ciphertext)

        fmt.Printf ("% s \ n", ciphertext)
        // Output: exampleplaintext
} 
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.