go之AES加密解密封装

最近在看golang,想着按照python项目去封装一套脚手架,日常项目中aes也是少不了的,这里就封装了下,代码中都含有注释,所以这里直接上代码:

golang中这几个包都是内置的,不用另外安装哟

/*
@Author   : Uyynot
@Email    : uyynot@qq.com
@Time     : 2024/1/18 10:01
@File     : main.py
@Project  : test
@Desc     :
*/
package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "errors"
    "fmt"
)

func main() {
    // 定义一个结构体,将key、iv和加解密全部封装到了一个结构体中
    aes := Aes{
        Key: []byte("Ay4j79B6XlKyOmzVVOsWCh5fUkHNUhav"),
        Iv:  []byte("M033mWWXiCvdg2tq"),
    }
    // 加密内容(要转成字节哟)
    data := []byte("01234567891234567")

    // 解密
    enData, err := aes.encrypt(data)
    fmt.Println("enData:", enData, string(enData))
    fmt.Println("err:", err)
    /**
    * 输出如下
    * enData: [77 65 103 86 51 99 101 84 119 68 81 50 116 69 105 117 68 66 51 103 82 72 108 90 71 50 86 86 51 113 76 65 98 117 79 76 79 82 55 76 49 72 107 61] MAgV3ceTwDQ2tEiuDB3gRHlZG2VV3qLAbuOLOR7L1Hk=
    * err: <nil>
    */

    // 解密
    deData, err1 := aes.decrypt(string(enData))
    fmt.Println("deData:", deData, string(deData))
    fmt.Println("err1:", err1)
    /**
    * 输出如下:
    * deData: [48 49 50 51 52 53 54 55 56 57 49 50 51 52 53 54 55] 01234567891234567
    * err1: <nil>
    */
}

// aes结构体及加解密方法
type Aes struct {
    Key []byte
    Iv  []byte
}

func (a *Aes) encrypt(data []byte) ([]byte, error) {
    block, err := aes.NewCipher(a.Key)
    if err != nil {
        return nil, err
    }
    //判断加密块的大小
    blockSize := block.BlockSize()
    //补充长度,最终补充的长度为blockSize的倍数
    encryptBytes := a.pkcs7Padding(data, blockSize)
    //初始化加密数据接收切片
    crypted := make([]byte, len(encryptBytes))
    //使用CBC加密模式
    mode := cipher.NewCBCEncrypter(block, a.Iv)
    //执行加密
    mode.CryptBlocks(crypted, encryptBytes)
    //进行base64编码
    encryptData := base64.StdEncoding.EncodeToString(crypted)
    return []byte(encryptData), nil
}

func (a *Aes) decrypt(encryData string) ([]byte, error) {
    block, err := aes.NewCipher(a.Key)
    if err != nil {
        return nil, err
    }
    //先使用base进行解码
    baseDeData, err := base64.StdEncoding.DecodeString(encryData)
    if err != nil {
        return nil, err
    }
    //初始化解密数据接收切片
    decrypted := make([]byte, len(baseDeData))
    //使用CBC解密模式
    mode := cipher.NewCBCDecrypter(block, a.Iv)

    //执行解密
    mode.CryptBlocks(decrypted, baseDeData)
    //去除填充
    decrypted, err = a.pkcs7UnPadding(decrypted)
    if err != nil {
        return nil, err
    }
    return decrypted, nil
}

// pkcs7Padding 填充
func (a *Aes) pkcs7Padding(data []byte, blockSize int) []byte {
    //判断缺少几位长度。最少1,最多 blockSize
    padding := blockSize - len(data)%blockSize
    //补足位数。把切片[]byte{byte(padding)}复制padding个
    padText := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(data, padText...)
}

// pkcs7UnPadding 移除
func (a *Aes) pkcs7UnPadding(data []byte) ([]byte, error) {
    length := len(data)
    if length == 0 {
        return nil, errors.New("加密字符串错误!")
    }
    //获取填充的个数
    unPadding := int(data[length-1])
    return data[:(length - unPadding)], nil
}
aes
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

以上代码使用的常用的CBC这种常用的加密模式,这种模式会在做系统漏洞扫描时报安全提醒,并推荐使用GCM模式,有关GCM加密模式后续会新启一篇文章,但是保不齐直接追加到内容最后哟

3个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!