V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
sunmoon1983
V2EX  ›  Go 编程语言

求一个 go 中的 aes 加密方法

  •  
  •   sunmoon1983 · 2021-12-02 14:51:08 +08:00 · 1924 次点击
    这是一个创建于 847 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要求如下:

    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)
    }
    
    6 条回复    2021-12-03 12:32:28 +08:00
    guader
        1
    guader  
       2021-12-02 17:56:03 +08:00
    他这不是 cbc ?
    sunmoon1983
        2
    sunmoon1983  
    OP
       2021-12-02 20:57:09 +08:00
    @guader 我不知道呀,他给的文档中说的是 ecb....我就没向 cbc 上想呀
    buffzty
        3
    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
        4
    buffzty  
       2021-12-03 01:42:04 +08:00
    我真是服 这个代码格式化到底咋弄
    sunmoon1983
        5
    sunmoon1983  
    OP
       2021-12-03 09:00:57 +08:00
    @buffzty 3Q ,能加密出来相要有结果了
    v2tudnew
        6
    v2tudnew  
       2021-12-03 12:32:28 +08:00
    @buffzty 只有主题可以是 Markdown 的....
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1190 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 18:15 · PVG 02:15 · LAX 11:15 · JFK 14:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.