求一个 go 中的 aes 加密方法

2021-12-02 14:51:08 +08:00
 sunmoon1983

要求如下:

str = `406BF0AD11310101220213481000320000`
key := `ER2Fb6ts3ECX`
通过 AES 加密(加解密算法 AES/工作模式 ECB /填充方式 NoPadding)并根据 base64
转码后字符串位:
rebZn7aj61hD3lfsUrhwFgVzPg4yYo9aseP/a4sNTRIh/Vtb0mziFfoHdOZBZ5uj

试过了论坛中一位大老的方法,出来的结果貌似不一样呀~

package xaes

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

type Aes struct {
	key []byte
}

func NewAes(key string) (*Aes) {
	if key == "" {
		panic("aes key empty")
	}
	sum := sha256.Sum256([]byte(key))
	return &Aes{
		key:sum[:],
	}
}

func (a *Aes) Encrypt(encodeBytes []byte) (val string, err error) {
	block, err := aes.NewCipher(a.key)
	if err != nil {
		return
	}
	blockSize := block.BlockSize()
	encodeBytes = zeroPadding(encodeBytes, blockSize)

	iv := make([]byte, blockSize)
	_,err = rand.Read(iv)
	if err != nil {
		return
	}

	blockMode := cipher.NewCBCEncrypter(block, iv)
	crypted := make([]byte, len(encodeBytes))
	blockMode.CryptBlocks(crypted, encodeBytes)

	iv = append(iv,crypted...)
	val = base64.StdEncoding.EncodeToString(iv)
	return
}


func (a *Aes) pkCS5Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func (a *Aes) Decrypt(decodeBytes []byte) (origData []byte,err error) {
	//decodeBytes, err := base64.StdEncoding.DecodeString(decodeStr)
	//if err != nil {
	//	return
	//}
	block, err := aes.NewCipher(a.key)
	if err != nil {
		return nil, err
	}
	if len(decodeBytes) < block.BlockSize() {
		err = errors.New("decodeBytes 长度不足")
		return
	}
	iv := decodeBytes[:block.BlockSize()]
	decodeBytes = decodeBytes[block.BlockSize():]

	blockMode := cipher.NewCBCDecrypter(block, iv)
	origData = make([]byte, len(decodeBytes))
	blockMode.CryptBlocks(origData, decodeBytes)
	origData = zeroUnPadding(origData)
	return
}

func (a *Aes) 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)
	return append(ciphertext, padText...)
}

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

调用方式

package main

import (
	"awesomeProject/xaes"
	"fmt"
)

func main()  {
	str := []byte("406BF0AD11310101220213481000320000")
	xa := xaes.NewAes("ER2Fb6ts3ECX")
	b,e:=xa.Encrypt(str)
	if e != nil{
		fmt.Println(e.Error())
		return
	}
	fmt.Println(b)
}
2129 次点击
所在节点    Go 编程语言
6 条回复
guader
2021-12-02 17:56:03 +08:00
他这不是 cbc ?
sunmoon1983
2021-12-02 20:57:09 +08:00
@guader 我不知道呀,他给的文档中说的是 ecb....我就没向 cbc 上想呀
buffzty
2021-12-03 01:41:02 +08:00
早上上班就看见你发了,晚上要睡了还没人回你 真是醉了
```go
package main

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

func main() {
str := []byte("406BF0AD11310101220213481000320000")
key := make([]byte, 16)
oriKey := []byte("ER2Fb6ts3ECX")
for k, v := range oriKey {
key[k] = v
}
cipher, _ := aes.NewCipher(key)
chunks := arrChunk(str, len(key))
buf := make([]byte, len(key))
encryptData := make([]byte, 0, (len(chunks)+1)*len(key))
for _, chunk := range chunks {
if len(chunk) < len(key) {
chunk = append(chunk, bytes.Repeat([]byte{0}, len(key)-len(chunk))...)
}
cipher.Encrypt(buf, chunk)
encryptData = append(encryptData, buf...)
}
fmt.Println(base64.StdEncoding.EncodeToString(encryptData))
}
func arrChunk(arr []byte, size int) [][]byte {
chunks := make([][]byte, 0)
chunk := make([]byte, 0, size)
for i := 0; i < len(arr); i++ {
chunk = append(chunk, arr[i])
if len(chunk) >= size {
chunks = append(chunks, chunk)
chunk = make([]byte, 0, size)
}
}
chunks = append(chunks, chunk)
return chunks
}
```
buffzty
2021-12-03 01:42:04 +08:00
我真是服 这个代码格式化到底咋弄
sunmoon1983
2021-12-03 09:00:57 +08:00
@buffzty 3Q ,能加密出来相要有结果了
v2tudnew
2021-12-03 12:32:28 +08:00
@buffzty 只有主题可以是 Markdown 的....

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/819541

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX