golang中的aes加密

aries 发表于 2021-12-03 822 次浏览 标签 : goaes

今天要和第三方的接口做对接,对方给了一组密钥的算法:

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

通过询问得知对方是java语言,所以嘛,貌似ecb nopadding这种方式在golang的标准库中是没有的,只有自力更生了,google一番,再加上大神的指点:

首先要说给你提供这个算法的人压根就不懂密码学。
因为 AES 的要求密钥的字节长度是 64 的倍数,可以是 128、192、256 等等(64 位因为不够安全已经被废弃),当成 ASCII 字符串的话长度就是 16 的倍数。随便给个字符串那不叫密钥,天知道对方用的编程语言或加密库是怎么处理这种不合法的密钥的 —— 是前补 0 了、是前补空了、是后补 0 了、是后补空了、还是怎么着?
而因为密钥的字节长度不确定,所以加密时的一个重要参数 BlockSize 也就不确定了。
得,靠猜吧。当成后补空吧。

得出下面的答案:

package main

import (
	"crypto/aes"
	"encoding/base64"
	"log"
)

func main() {
	origin := []byte("406BF0AD11310101220213481000320000")
	key := []byte("ER2Fb6ts3ECX")

	encrypted := AesEncryptECB(origin, key)
	log.Println("encrypted: ", encrypted)
	decrypted := AesDecryptECB(encrypted, key)
	log.Println("decrypted: ", string(decrypted))
}

func AesEncryptECB(origData []byte, key []byte) string {
	cipher, _ := aes.NewCipher(generateKey(key))
	length := (len(origData) + aes.BlockSize) / aes.BlockSize
	plain := make([]byte, length*aes.BlockSize)
	copy(plain, origData)

	encrypted := make([]byte, len(plain))
	// Block encryption
	for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
		cipher.Encrypt(encrypted[bs:be], plain[bs:be])
	}

	return base64.StdEncoding.EncodeToString(encrypted)
}

func AesDecryptECB(str string, key []byte) (decrypted []byte) {
	encrypted, _ := base64.StdEncoding.DecodeString(str)

	cipher, _ := aes.NewCipher(generateKey(key))
	decrypted = make([]byte, len(encrypted))
	for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
		cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
	}

	trim := 0
	if len(decrypted) > 0 {
		trim = len(decrypted) - int(decrypted[len(decrypted)-1])
	}
	return decrypted[:trim]
}

func generateKey(key []byte) (genKey []byte) {
	genKey = make([]byte, 16)
	copy(genKey, key)
	for i := 16; i < len(key); {
		for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
			genKey[j] ^= key[i]
		}
	}
	return genKey
}

0条评论

如需评论,请填写表单。
换一个

记住我的信息