golang中的aes加密
今天要和第三方的接口做对接,对方给了一组密钥的算法:
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
}