Preface
In modern data security, encryption and decryption are extremely important links. Among them, the Advanced Encryption Standard (AES) is one of the most widely used encryption algorithms. This article will introduce how to use Golang to implement AES encryption and decryption.
1. What is AES?
Advanced Encryption Standard (AES) is a symmetric encryption algorithm, that is, encryption and decryption use the same key. AES supports 128, 192 and 256-bit key lengths, and the longer the key provides higher security, but also requires more computing resources. AES uses a fixed 128-bit block size, and different key lengths and block sizes can be combined into different AES variants such as AES-128, AES-192, and AES-256.
2. Code implementation
Here is a simple example of using Golang to implement AES encryption and decryption:
package main import ( "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" ) func main() { key := []byte("myverystrongpasswordo32bitlength") // 32 bytes key for AES-256 plaintext := []byte("Hello, World!") block, err := (key) if err != nil { panic(err) } ciphertext := make([]byte, len(plaintext)) stream := (block, make([]byte, ())) (ciphertext, plaintext) ("Encrypted: %s\n", (ciphertext)) decrypted := make([]byte, len(ciphertext)) stream = (block, make([]byte, ())) (decrypted, ciphertext) ("Decrypted: %s\n", decrypted) }
In this example, we first create a new cipher block. We then create a new CTR (Counter) mode cipher stream and use it to encrypt our plaintext.
For decryption, we created a new CTR mode cipher stream and used it to decrypt our cipher text.
Expand: Three mode implementations of AES encryption and decryption
package main import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/hex" "io" "log" ) func main() { origData := []byte("Jie Ge's technical grocery store") // Data to be encrypted key := []byte("ABCDEFGHIJKLMNOP") // Encrypted key ("original:", string(origData)) ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted := AesEncryptCBC(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted := AesDecryptCBC(encrypted, key) ("Decryption result:", string(decrypted)) ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted = AesEncryptECB(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted = AesDecryptECB(encrypted, key) ("Decryption result:", string(decrypted)) ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted = AesEncryptCFB(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted = AesDecryptCFB(encrypted, key) ("Decryption result:", string(decrypted)) }
CBC/ECB/CFB decryption method
// =================== CBC ====================== func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) { // Grouping key // NewCipher This function limits the length of input k must be 16, 24 or 32 block, _ := (key) blockSize := () // Get the length of the key block origData = pkcs5Padding(origData, blockSize) // Complete code blockMode := (block, key[:blockSize]) // Encryption mode encrypted = make([]byte, len(origData)) // Create an array (encrypted, origData) // Encryption return encrypted } func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) { block, _ := (key) // Grouping key blockSize := () // Get the length of the key block blockMode := (block, key[:blockSize]) // Encryption mode decrypted = make([]byte, len(encrypted)) // Create an array (decrypted, encrypted) // Decrypt decrypted = pkcs5UnPadding(decrypted) // Remove the complete code return decrypted } func pkcs5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := ([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func pkcs5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } // =================== ECB ====================== func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) { cipher, _ := (generateKey(key)) length := (len(origData) + ) / plain := make([]byte, length*) copy(plain, origData) pad := byte(len(plain) - len(origData)) for i := len(origData); i < len(plain); i++ { plain[i] = pad } encrypted = make([]byte, len(plain)) // Packet block encryption for bs, be := 0, (); bs <= len(origData); bs, be = bs+(), be+() { (encrypted[bs:be], plain[bs:be]) } return encrypted } func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) { cipher, _ := (generateKey(key)) decrypted = make([]byte, len(encrypted)) // for bs, be := 0, (); bs < len(encrypted); bs, be = bs+(), be+() { (decrypted[bs:be], encrypted[bs:be]) } trim := 0 if len(decrypted) > 0 { trim = len(decrypted) - int(decrypted[len(decrypted)-1]) } return decrypted[:trim] } func generateKey(key []byte) (genKey []byte) { genKey = make([]byte, 16) copy(genKey, key) for i := 16; i < len(key); { for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { genKey[j] ^= key[i] } } return genKey } // =================== CFB ====================== func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) { block, err := (key) if err != nil { panic(err) } encrypted = make([]byte, +len(origData)) iv := encrypted[:] if _, err := (, iv); err != nil { panic(err) } stream := (block, iv) (encrypted[:], origData) return encrypted } func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) { block, _ := (key) if len(encrypted) < { panic("ciphertext too short") } iv := encrypted[:] encrypted = encrypted[:] stream := (block, iv) (encrypted, encrypted) return encrypted }
Output result:
2022/08/02 20:02:24 Original text: Brother Jie’s technical grocery store
2022/08/02 20:02:24 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/02 20:02:24 Password (hex): 6b11cae9b7831c3bbf1782a69e5504f5c32da4f6a5771e017f3a2d5ae8bf10b4
2022/08/02 20:02:24 Password (base64): axHK6beDHDu/F4KmnlUE9cMtpPaldx4BfzotWui/ELQ=
2022/08/02 20:02:24 Decryption result: Brother Jie’s technical grocery store
2022/08/02 20:02:24 ------------------------------------------------------------------------------------------------------------
2022/08/02 20:02:24 Password (hex): eb69b3c7921373408f371a9f608c5915bc72d09a06994af0788542bab88387a9
2022/08/02 20:02:24 Password (base64): 62mzx5ITc0CPNxqfYIxZFbxy0JoGmUrweIVCuriDh6k=
2022/08/02 20:02:24 Decryption result: Brother Jie’s technical grocery store
2022/08/02 20:02:24 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/02 20:02:24 Password (hex): 483c4133a0ba7e0c8655d9e2a23acae4b13494a6036ab231b99bc01e7676fc0bb8c6ab7cbe6953ab
2022/08/02 20:02:24 Password (base64): SDxBM6C6fgyGVdniojrK5LE0lKYDarIxuZvAHnZ2/Au4xqt8vmlTqw==
2022/08/02 20:02:24 Decryption result: Brother Jie’s technical grocery store
Decryption of test cases
func TestAesEcbDecrypt(t *) { origData := []byte("Jie Ge's technical grocery store") // Data to be encrypted key := []byte("^%TytgUYGsefsq7JYU5F2OIJ") // Encrypted key ("original:", string(origData)) ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted := AesEncryptCBC(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted := AesDecryptCBC(encrypted, key) ("Decryption result:", string(decrypted)) ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted = AesEncryptECB(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted = AesDecryptECB(encrypted, key) ("Decryption result:", string(decrypted)) ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted = AesEncryptCFB(origData, key) ("Secret text(hex):", (encrypted)) ("Secret text(base64):", (encrypted)) decrypted = AesDecryptCFB(encrypted, key) ("Decryption result:", string(decrypted)) }
Output result:
=== RUN TestAesEcbDecrypt
2022/08/03 11:23:50 Original text: Brother Jie’s technical grocery store
2022/08/03 11:23:50 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/03 11:23:50 Password (hex): 606072d10a591454e68069ff690e63ec0cd4dcd832922aa715aaf682ff645799
2022/08/03 11:23:50 Password (base64): YGBy0QpZFFTmgGn/aQ5j7AzU3NgykiqnFar2gv9kV5k=
2022/08/03 11:23:50 Decryption result: Brother Jie’s technical grocery store
2022/08/03 11:23:50 ------------------------------------------------------------------------------------------------------------
2022/08/03 11:23:50 Password (hex): d31dc8357a8ab488e453b0740e91d0c241b7743b6e02f942c0a15a4417ad518a
2022/08/03 11:23:50 Password (base64): 0x3INXqKtIjkU7B0DpHQwkG3dDtuAvlCwKFaRBetUYo=
2022/08/03 11:23:50 Decryption result: Brother Jie’s technical grocery store
2022/08/03 11:23:50 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/03 11:23:50 Password (hex): e6da19018b091415326822560d16a8d614fcb0cad71bdbf3b3afe4bf3633d95e4036c5ed2a25272e
2022/08/03 11:23:50 Password (base64): 5toZAYsJFBUyaCJWDRao1hT8sMrXG9vzs6/kvzYz2V5ANsXtKiUnLg==
2022/08/03 11:23:50 Decryption result: Brother Jie’s technical grocery store
--- PASS: TestAesEcbDecrypt (0.04s)
PASS
Decrypt only
func TestAesEcbDecrypt(t *) { key := []byte("^%TytgUYGsefsq7JYU5F2OIJ") // Encrypted key ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted,err1 := ("606072d10a591454e68069ff690e63ec0cd4dcd832922aa715aaf682ff645799") if err1 != nil { (err1) } decrypted := AesDecryptCBC(encrypted, key) ("Decryption result:", string(decrypted)) ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted,err2 := ("d31dc8357a8ab488e453b0740e91d0c241b7743b6e02f942c0a15a4417ad518a") if err2 != nil { (err2) } decrypted = AesDecryptECB(encrypted, key) ("Decryption result:", string(decrypted)) ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------) encrypted,err3 := ("ea9e17002777f1bc791d2be328c65206fff543c94b29341404926b6d0feb9a22428e6749c603352d") if err3 != nil { (err3) } decrypted = AesDecryptCFB(encrypted, key) ("Decryption result:", string(decrypted)) }
Output result:
=== RUN TestAesEcbDecrypt
2022/08/03 11:21:27 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/03 11:21:27 Decryption result: Brother Jie’s technical grocery store
2022/08/03 11:21:27 ------------------------------------------------------------------------------------------------------------
2022/08/03 11:21:27 Decryption result: Brother Jie’s technical grocery store
2022/08/03 11:21:27 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022/08/03 11:21:27 Decryption result: Brother Jie’s technical grocery store
--- PASS: TestAesEcbDecrypt (0.04s)
PASS
RSA
First use openssl to generate public and private keys
import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" ) // Private key generation//openssl genrsa -out rsa_private_key.pem 1024 var privateKey = []byte(` -----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDcGsUIIAINHfRTdMmgGwLrjzfMNSrtgIf4EGsNaYwmC1GjF/bM h0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdTnCDPPZ7oV7p1B9Pud+6zPaco qDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Zy682X1+R1lRK8D+vmQIDAQAB AoGAeWAZvz1HZExca5k/hpbeqV+0+VtobMgwMs96+U53BpO/VRzl8Cu3CpNyb7HY 64L9YQ+J5QgpPhqkgIO0dMu/0RIXsmhvr2gcxmKObcqT3JQ6S4rjHTln49I2sYTz 7JEH4TcplKjSjHyq5MhHfA+CV2/AB2BO6G8limu7SheXuvECQQDwOpZrZDeTOOBk z1vercawd+J9ll/FZYttnrWYTI1sSF1sNfZ7dUXPyYPQFZ0LQ1bhZGmWBZ6a6wd9 R+PKlmJvAkEA6o32c/WEXxW2zeh18sOO4wqUiBYq3L3hFObhcsUAY8jfykQefW8q yPuuL02jLIajFWd0itjvIrzWnVmoUuXydwJAXGLrvllIVkIlah+lATprkypH3Gyc YFnxCTNkOzIVoXMjGp6WMFylgIfLPZdSUiaPnxby1FNM7987fh7Lp/m12QJAK9iL 2JNtwkSR3p305oOuAz0oFORn8MnB+KFMRaMT9pNHWk0vke0lB1sc7ZTKyvkEJW0o eQgic9DvIYzwDUcU8wJAIkKROzuzLi9AvLnLUrSdI6998lmeYO9x7pwZPukz3era zncjRK3pbVkv0KrKfczuJiRlZ7dUzVO0b6QJr8TRAA== -----END RSA PRIVATE KEY----- `) // Public key: Generate based on private key//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem var publicKey = []byte(` -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcGsUIIAINHfRTdMmgGwLrjzfM NSrtgIf4EGsNaYwmC1GjF/bMh0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdT nCDPPZ7oV7p1B9Pud+6zPacoqDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Z y682X1+R1lRK8D+vmQIDAQAB -----END PUBLIC KEY----- `) // Encryptionfunc RsaEncrypt(origData []byte) ([]byte, error) { //Decrypt the public key in pem format block, _ := (publicKey) if block == nil { return nil, ("public key error") } // parse the public key pubInterface, err := () if err != nil { return nil, err } // Type assertion pub := pubInterface.(*) //encryption return rsa.EncryptPKCS1v15(, pub, origData) } // Decryptfunc RsaDecrypt(ciphertext []byte) ([]byte, error) { //Decryption block, _ := (privateKey) if block == nil { return nil, ("private key error!") } //Parse the private key in PKCS1 format priv, err := x509.ParsePKCS1PrivateKey() if err != nil { return nil, err } // Decrypt return rsa.DecryptPKCS1v15(, priv, ciphertext) } func main() { data, _ := RsaEncrypt([]byte("hello world")) ((data)) origData, _ := RsaDecrypt(data) (string(origData)) }
3. Summary
With this simple example, we can see that using Golang to implement AES encryption and decryption is very straightforward. Although in practical applications, you need to consider how to safely generate and store keys, how to handle errors, and how to handle data of different lengths, the basic AES encryption and decryption processes are the same. Hope this article helps you.
The above is the detailed content of the code examples for using Golang to implement AES encryption and decryption. For more information about Golang AES encryption and decryption, please follow my other related articles!