尝试在Go中模拟基本上是AES ECB模式加密的算法。
这是我到目前为止所拥有的
func Decrypt(data []byte) []byte {
cipher, err := aes.NewCipher([]byte(KEY))
if err == nil {
cipher.Decrypt(data, PKCS5Pad(data))
return data
}
return nil
}
我还有一个PKCS5Padding算法,经过测试和工作,它首先填充数据。我无法找到有关如何在Go AES包中切换加密模式的任何信息(它绝对不在the docs中)。
我有另一种语言的代码,这就是我知道这个算法没有正常工作的方式。
编辑:这是我在问题页面上解释的方法
func AESECB(ciphertext []byte) []byte {
cipher, _ := aes.NewCipher([]byte(KEY))
fmt.Println("AESing the data")
bs := 16
if len(ciphertext)%bs != 0 {
panic("Need a multiple of the blocksize")
}
plaintext := make([]byte, len(ciphertext))
for len(plaintext) > 0 {
cipher.Decrypt(plaintext, ciphertext)
plaintext = plaintext[bs:]
ciphertext = ciphertext[bs:]
}
return plaintext
}
这实际上并没有返回任何数据,也许我在将其从编写内容更改为decripting时搞砸了一些内容
答案 0 :(得分:7)
欧洲央行故意因为不安全而被排除在外,请检查issue 5597。
答案 1 :(得分:5)
ESB是一种非常简单的操作方式。要加密的数据被分成字节块,所有字节块都具有相同的大小。对于每个块,应用密码,在这种情况下为AES,生成加密块。
下面的代码片段在ECB中解密AES-128数据(请注意,块大小为16字节):
package main
import (
"crypto/aes"
)
func DecryptAes128Ecb(data, key []byte) []byte {
cipher, _ := aes.NewCipher([]byte(key))
decrypted := make([]byte, len(data))
size := 16
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
cipher.Decrypt(decrypted[bs:be], data[bs:be])
}
return decrypted
}
如@OneOfOne所述,ECB不安全且易于检测,因为重复的块将始终加密到相同的加密块。这个Crypto SE answer给出了很好的解释原因。
答案 2 :(得分:3)
我使用了您的代码,所以我觉得有必要告诉您如何修复它。
我正在Go中为此问题执行cryptopals challenges。
我会告诉你错误,因为代码大部分是正确的。
for len(plaintext) > 0 {
cipher.Decrypt(plaintext, ciphertext)
plaintext = plaintext[bs:]
ciphertext = ciphertext[bs:]
}
循环确实会对数据进行解密,但不会将其放在任何位置。它只是将两个数组移位而不产生输出。
i := 0
plaintext := make([]byte, len(ciphertext))
finalplaintext := make([]byte, len(ciphertext))
for len(ciphertext) > 0 {
cipher.Decrypt(plaintext, ciphertext)
ciphertext = ciphertext[bs:]
decryptedBlock := plaintext[:bs]
for index, element := range decryptedBlock {
finalplaintext[(i*bs)+index] = element
}
i++
plaintext = plaintext[bs:]
}
return finalplaintext[:len(finalplaintext)-5]
这项新改进的作用是将解密后的数据存储到名为finalplaintext的新[]字节中。如果您返回,则会获得数据。
这样做非常重要,因为Decrypt函数一次只能处理一个块大小。
我返回一片,因为我怀疑它是填充的。我是密码学新手,所以任何人都可以随意纠正/修改它。
答案 3 :(得分:1)
理想情况下,您希望实现 crypto/cipher#BlockMode 接口。自从 官方不存在,我用 crypto/cipher#NewCBCEncrypter 作为 起点:
package ecb
import "crypto/cipher"
type ecbEncrypter struct { cipher.Block }
func newECBEncrypter(b cipher.Block) cipher.BlockMode {
return ecbEncrypter{b}
}
func (x ecbEncrypter) BlockSize() int {
return x.Block.BlockSize()
}
func (x ecbEncrypter) CryptBlocks(dst, src []byte) {
size := x.BlockSize()
if len(src) % size != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.Encrypt(dst, src)
src, dst = src[size:], dst[size:]
}
}
答案 4 :(得分:-1)
我对一些事感到困惑。
首先我需要aes-256版本的上述算法,但显然aes.Blocksize(16)在给定的密钥长度为32时不会改变。因此,给出一个长度为32的密钥就足够了使算法成为aes-256
其次,解密值仍包含填充,填充值根据加密字符串的长度而变化。例如。当有5个填充字符时,填充字符本身将为5。
这是我的函数,它返回一个字符串:
func DecryptAes256Ecb(hexString string, key string) string {
data, _ := hex.DecodeString(hexString)
cipher, _ := aes.NewCipher([]byte(key))
decrypted := make([]byte, len(data))
size := 16
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
cipher.Decrypt(decrypted[bs:be], data[bs:be])
}
// remove the padding. The last character in the byte array is the number of padding chars
paddingSize := int(decrypted[len(decrypted)-1])
return string(decrypted[0 : len(decrypted)-paddingSize])
}