go AES 加解密算法

更新时间: 2022-03-04 16:06:59 go语言如何实现AES加解密算法呢?人狠话不多,直接上代码

package main

import (

"crypto/aes"

"crypto/cipher"

"crypto/rand"

"encoding/hex"

"fmt"

"io"

)

/*

AES CBC 加密

key:加密key

plaintext:加密明文

ciphertext:解密返回字节字符串[ 整型以十六进制方式显示]

*/

func AESCBCEncrypt(key, plaintext string) (ciphertext string ,error string) {

plainbyte := []byte(plaintext)

keybyte := []byte(key)

if len(plainbyte)%aes.BlockSize != 0 {

return "" ,"plaintext is not a multiple of the block size"

}

block, err := aes.NewCipher(keybyte)

if err != nil {

return "" ,err.Error()

}

cipherbyte := make([]byte, aes.BlockSize+len(plainbyte))

iv := cipherbyte[:aes.BlockSize]

if _, err := io.ReadFull(rand.Reader, iv); err != nil {

return "" ,err.Error()

}

mode := cipher.NewCBCEncrypter(block, iv)

mode.CryptBlocks(cipherbyte[aes.BlockSize:], plainbyte)

ciphertext = fmt.Sprintf("%x\n", cipherbyte)

return

}

/*

AES CBC 解码

key:解密key

ciphertext:加密返回的串

plaintext:解密后的字符串

*/

func AESCBCDecrypter(key, ciphertext string) (plaintext string , error string) {

cipherbyte, _ := hex.DecodeString(ciphertext)

keybyte := []byte(key)

block, err := aes.NewCipher(keybyte)

if err != nil {

return "" ,err.Error()

}

if len(cipherbyte) < aes.BlockSize {

return "" ,"ciphertext too short"

}

iv := cipherbyte[:aes.BlockSize]

cipherbyte = cipherbyte[aes.BlockSize:]

if len(cipherbyte)%aes.BlockSize != 0 {

return "" ,"ciphertext is not a multiple of the block size"

}

mode := cipher.NewCBCDecrypter(block, iv)

mode.CryptBlocks(cipherbyte, cipherbyte)

//fmt.Printf("%s\n", ciphertext)

plaintext = string(cipherbyte[:])

return

}

/*

AES GCM 加密

key:加密key

plaintext:加密明文

ciphertext:解密返回字节字符串[ 整型以十六进制方式显示]

*/

func AESGCMEncrypt(key, plaintext string) (ciphertext string, noncetext string, error string) {

plainbyte := []byte(plaintext)

keybyte := []byte(key)

block, err := aes.NewCipher(keybyte)

if err != nil {

return "", "", err.Error()

}

// 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。

nonce := make([]byte, 12)

if _, err := io.ReadFull(rand.Reader, nonce); err != nil {

return "", "", err.Error()

}

aesgcm, err := cipher.NewGCM(block)

if err != nil {

return "", "", err.Error()

}

cipherbyte := aesgcm.Seal(nil, nonce, plainbyte, nil)

ciphertext = fmt.Sprintf("%x\n", cipherbyte)

noncetext = fmt.Sprintf("%x\n", nonce)

return ciphertext, noncetext, ""

}

/*

AES GCM 解码

key:解密key

ciphertext:加密返回的串

plaintext:解密后的字符串

*/

func AESGCMDecrypter(key, ciphertext, noncetext string) (plaintext string , error string) {

if len(noncetext) < 24 {

return "", "noncetext too short"

}

nonce, _ := hex.DecodeString(noncetext)

cipherbyte, _ := hex.DecodeString(ciphertext)

keybyte := []byte(key)

block, err := aes.NewCipher(keybyte)

if err != nil {

return "", err.Error()

}

aesgcm, err := cipher.NewGCM(block)

if err != nil {

return "", err.Error()

}

plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil)

if err != nil {

return "", err.Error()

}

//fmt.Printf("%s\n", ciphertext)

plaintext = string(plainbyte[:])

return

}

func main() {

key := "example key 1234"

plaintext := "exampleplaintext"

ciphertext,_ := AESCBCEncrypt(key, plaintext)

//fmt.Println(ciphertext)

//

//plaintext = AESCBCDecrypter(key, ciphertext)

//fmt.Println(plaintext)

///GCM

noncetext := "mac"

ciphertext, noncetext, _ = AESGCMEncrypt(key, plaintext)

fmt.Println(ciphertext)

//ciphertext = "grt344gdfgsdfsfsfsfsfsdfsf"

//noncetext = "2b73b376e34aed44b646a4a4"

fmt.Println(noncetext)

plaintext,err := AESGCMDecrypter(key, ciphertext, noncetext)

fmt.Println(err)

fmt.Println(plaintext)

}