Golang实现AES对称加密的过程详解

作者:写Golang的小张 时间:2024-01-31 06:44:22 

AES加密

AES对称加密简介
AES是一个对称密码,旨在取代DES成为广泛使用的标准。是美国联邦政府采用的一种区块加密标准。

AES对称加密过程
加密解密算法的输入是一个128位分组。这些分组被描述成4×4的字节方阵,这个分组被复制到数组中,并在加密和解密的每一阶段都被修改。在字节方阵中,每一格都是一个字,包含了4字节。在矩阵中字是按列排序的。
加密由N轮构成,轮数依赖于密钥长度:16字节密钥对应10轮,24字节密钥对应12轮,32字节对应14轮。

AES加密模式

1.电码本模式(Electronic Codebook Book (ECB)

ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。

2.密码分组链接模式(Cipher Block Chaining (CBC))

这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。

3.密码反馈模式(Cipher FeedBack (CFB))
隐藏了明文模式,分组密码转化为流模式,可以及时加密传送小于分组的数据

4.OFB(Output FeedBack,输出反馈)模式
隐藏了明文模式;,分组密码转化为流模式,可以及时加密传送小于分组的数据

AES填充方式
AES支持支持几种填充:NoPadding,PKCS5Padding,ISO10126Padding,PaddingMode.Zeros,PaddingMode.PKCS7。对于AES来说PKCS5Padding和PKCS7Padding是完全一样的,不同在于PKCS5限定了块大小为8bytes而PKCS7没有限定。因此对于AES来说两者完全相同

Golang实现AES加密解密

下面附上Golang实现AES加密ECB模式的源码:


package main
import (
"bytes"
"crypto/aes"
"fmt"
"testing"
)

//ECB模式解密
func ECBDecrypt(crypted, key []byte) ([]byte, error) {
if !validKey(key) {
return nil, fmt.Errorf("秘钥长度错误,当前传入长度为 %d",len(key))
}
if len(crypted) < 1 {
return nil, fmt.Errorf("源数据长度不能为0")
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(crypted)%block.BlockSize() != 0 {
return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d",block.BlockSize(), len(crypted))
}
var dst []byte
tmpData := make([]byte, block.BlockSize())

for index := 0; index < len(crypted); index += block.BlockSize() {
block.Decrypt(tmpData, crypted[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
dst, err = PKCS5UnPadding(dst)
if err != nil {
return nil, err
}
return dst, nil
}

//ECB模式加密
func ECBEncrypt(src, key []byte) ([]byte, error) {
if !validKey(key) {
return nil, fmt.Errorf("秘钥长度错误, 当前传入长度为 %d",len(key))
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(src) < 1 {
return nil, fmt.Errorf("源数据长度不能为0")
}
src = PKCS5Padding(src, block.BlockSize())
if len(src)%block.BlockSize() != 0 {
return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d",block.BlockSize(), len(src))
}
var dst []byte
tmpData := make([]byte, block.BlockSize())
for index := 0; index < len(src); index += block.BlockSize() {
block.Encrypt(tmpData, src[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
return dst, nil
}

// PKCS5填充
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}

// 去除PKCS5填充
func PKCS5UnPadding(origData []byte) ([]byte, error) {
length := len(origData)
unpadding := int(origData[length-1])

if length < unpadding {
return nil, fmt.Errorf("invalid unpadding length")
}
return origData[:(length - unpadding)], nil
}

// 秘钥长度验证
func validKey(key []byte) bool {
k := len(key)
switch k {
default:
return false
case 16, 24, 32:
return true
}
}

func TestAes(t *testing.T){
srcData := "hello world !"
key := []byte("abcdabcdabcdabcdabcdabcdabcdabcd")
//测试加密
encData ,err := ECBEncrypt([]byte(srcData),(key))
if err != nil {
t.Errorf(err.Error())
return
}

//测试解密
decData ,err := ECBDecrypt(encData,key)
if err != nil {
t.Errorf(err.Error())
return
}
t.Log(string(decData))
}

来源:https://blog.csdn.net/weixin_46040684/article/details/116993628

标签:go,AES,加密
0
投稿

猜你喜欢

  • Python netmiko模块的使用

    2021-07-04 06:42:51
  • 利用django和mysql实现一个简单的web登录页面

    2024-01-13 18:16:16
  • Python使用scipy保存图片的一些注意点

    2023-12-01 06:06:58
  • 细说NumPy数组的四种乘法的使用

    2023-08-16 10:33:28
  • 深入浅出SQL之左连接、右连接和全连接

    2009-08-30 15:14:00
  • ASP生成柱型体,折线图,饼图源代码

    2007-09-20 12:56:00
  • Python定时任务工具之APScheduler使用方式

    2022-02-02 05:50:51
  • JS版图片放大镜效果

    2024-04-30 08:50:57
  • Django如何创作一个简单的最小程序

    2022-09-04 04:57:28
  • 用Assets 面板为你的站点定做颜色

    2007-02-03 11:39:00
  • Smush it - 一款图片压缩的Firefox插件,很好,很强大!

    2009-04-12 20:09:00
  • 在Python的Flask框架中使用日期和时间的教程

    2022-08-14 21:13:09
  • 微信小程序输入多行文本的实战记录

    2023-09-10 15:29:51
  • Python操作lxml库实战之Xpath篇

    2023-12-26 23:08:00
  • Python如何通过ip2region解析IP获得地域信息

    2021-08-02 12:59:04
  • JS页面获取 session 值,作用域和闭包学习笔记

    2024-04-22 13:23:06
  • python自动生成证件号的方法示例

    2023-05-25 07:42:11
  • Python实现获取汉字偏旁部首的方法示例【测试可用】

    2022-10-26 16:42:16
  • Python网络编程详解

    2022-01-09 15:25:10
  • Vue.js设计与实现无限递归学习总结

    2024-04-28 10:53:53
  • asp之家 网络编程 m.aspxhome.com