如何使用 AES-256 加密特殊字符或数字?
How do I encrypt special characters or numbers using AES-256?
我想在没有任何 GCM 处理的情况下使用 AES-256 在 Go 中加密一个字符串,以便与 MQL4 进行比较。我在尝试加密特殊字符或数字时遇到问题。我应该以某种方式预处理我的明文吗?我是 Go 的新手,所以我们将不胜感激;我的代码在这个解释下面。
如果我加密明文“This is a secret”然后解密密文(编码为十六进制),我会得到相同的结果(即“This is a secret”)。 pt是下面代码中明文的变量名
如果我尝试加密“This is a secret; 1234”,密文末尾有一组零,当我解密时我只会得到“This is a secret”。 MQL4 中的类似密文末尾没有零并且正确解密。
如果我尝试仅加密“1234”,我会收到构建错误,源于“crypto/aes.(*aesCipherAsm).Encrypt(0xc0000c43c0, 0xc0000ac058, 0x4, 0x4, 0xc0000ac070, 0x4, 0x8)
C:/Program Files/Go/src/crypto/aes/cipher_asm.go:60 +0x125"
这是我的代码:
package main
import (
"crypto/aes"
"encoding/hex"
"fmt"
)
func main() {
// cipher key
key := "thisis32bitlongpassphraseimusing"
// plaintext
pt := "This is a secret"
// pt := "This is a secret; 1234" // zeroes in ciphertext
// pt := "1234" // doesn't build
c := EncryptAES([]byte(key), pt)
// plaintext
fmt.Println(pt)
// ciphertext
fmt.Println(c)
// decrypt
DecryptAES([]byte(key), c)
}
func EncryptAES(key []byte, plaintext string) string {
c, err := aes.NewCipher(key)
CheckError(err)
out := make([]byte, len(plaintext))
c.Encrypt(out, []byte(plaintext))
return hex.EncodeToString(out)
}
func DecryptAES(key []byte, ct string) {
ciphertext, _ := hex.DecodeString(ct)
c, err := aes.NewCipher(key)
CheckError(err)
pt := make([]byte, len(ciphertext))
c.Decrypt(pt, ciphertext)
s := string(pt[:])
fmt.Println("DECRYPTED:", s)
}
func CheckError(err error) {
if err != nil {
panic(err)
}
}
您正在此处创建原始 AES 加密器。 AES 只能精确加密 16 个字节的明文,生成恰好 16 个字节的密文。您的第一个示例 "This is a secret"
正好是 16 个字节长,因此它按预期工作。你的第二个例子太长了。只有前 16 个字节被加密。第三个示例太短,您可能 运行 进入未初始化的内存。
您文本中的具体字符无关紧要。对原始字节而非字母进行加密。
为了加密更大(或更小)的文本块,您需要在 AES 之上使用分组密码模式。常见模式有 GCM、CBC 和 CTR,但还有许多其他模式。在大多数情况下,当有人在没有任何限定词的情况下说“AES”时,他们指的是 AES-CBC。 (GCM 正变得越来越流行,它是一种很棒的模式,但它还没有流行到人们认为它已经相当流行的程度。)
我对 MQL4 一无所知,但我假设您正在尝试重新实现 CryptEncode?我没有看到任何关于他们如何进行加密的文档。您需要知道他们使用什么模式、他们如何推导他们的密钥、他们如何生成(并可能编码)他们的 IV、他们是否包括 HMAC 或其他身份验证,等等。你需要确切地知道他们是如何实现他们所说的“CRYPT_AES256”的意思的。没有人,这个标准答案。
MQL4 仅支持非常具体的 AES 加密实现,除非您在其他代码中使用正确的设置,否则您将无法实现两个平台之间的兼容性。
具体来说,您需要确保实施以下内容:
- 填充模式:零
- 密码模式:ECB(因此没有 IV)
- 密钥大小:256
- 块大小:128
您还需要记住,在 MQL4 中,encryption/decryption 是一个两阶段过程(到 AES256,然后到 BASE64)。
您可以尝试使用在线 AES encryption/decryption 工具来验证您的结果:The online toolbox
我想在没有任何 GCM 处理的情况下使用 AES-256 在 Go 中加密一个字符串,以便与 MQL4 进行比较。我在尝试加密特殊字符或数字时遇到问题。我应该以某种方式预处理我的明文吗?我是 Go 的新手,所以我们将不胜感激;我的代码在这个解释下面。
如果我加密明文“This is a secret”然后解密密文(编码为十六进制),我会得到相同的结果(即“This is a secret”)。 pt是下面代码中明文的变量名
如果我尝试加密“This is a secret; 1234”,密文末尾有一组零,当我解密时我只会得到“This is a secret”。 MQL4 中的类似密文末尾没有零并且正确解密。
如果我尝试仅加密“1234”,我会收到构建错误,源于“crypto/aes.(*aesCipherAsm).Encrypt(0xc0000c43c0, 0xc0000ac058, 0x4, 0x4, 0xc0000ac070, 0x4, 0x8) C:/Program Files/Go/src/crypto/aes/cipher_asm.go:60 +0x125"
这是我的代码:
package main
import (
"crypto/aes"
"encoding/hex"
"fmt"
)
func main() {
// cipher key
key := "thisis32bitlongpassphraseimusing"
// plaintext
pt := "This is a secret"
// pt := "This is a secret; 1234" // zeroes in ciphertext
// pt := "1234" // doesn't build
c := EncryptAES([]byte(key), pt)
// plaintext
fmt.Println(pt)
// ciphertext
fmt.Println(c)
// decrypt
DecryptAES([]byte(key), c)
}
func EncryptAES(key []byte, plaintext string) string {
c, err := aes.NewCipher(key)
CheckError(err)
out := make([]byte, len(plaintext))
c.Encrypt(out, []byte(plaintext))
return hex.EncodeToString(out)
}
func DecryptAES(key []byte, ct string) {
ciphertext, _ := hex.DecodeString(ct)
c, err := aes.NewCipher(key)
CheckError(err)
pt := make([]byte, len(ciphertext))
c.Decrypt(pt, ciphertext)
s := string(pt[:])
fmt.Println("DECRYPTED:", s)
}
func CheckError(err error) {
if err != nil {
panic(err)
}
}
您正在此处创建原始 AES 加密器。 AES 只能精确加密 16 个字节的明文,生成恰好 16 个字节的密文。您的第一个示例 "This is a secret"
正好是 16 个字节长,因此它按预期工作。你的第二个例子太长了。只有前 16 个字节被加密。第三个示例太短,您可能 运行 进入未初始化的内存。
您文本中的具体字符无关紧要。对原始字节而非字母进行加密。
为了加密更大(或更小)的文本块,您需要在 AES 之上使用分组密码模式。常见模式有 GCM、CBC 和 CTR,但还有许多其他模式。在大多数情况下,当有人在没有任何限定词的情况下说“AES”时,他们指的是 AES-CBC。 (GCM 正变得越来越流行,它是一种很棒的模式,但它还没有流行到人们认为它已经相当流行的程度。)
我对 MQL4 一无所知,但我假设您正在尝试重新实现 CryptEncode?我没有看到任何关于他们如何进行加密的文档。您需要知道他们使用什么模式、他们如何推导他们的密钥、他们如何生成(并可能编码)他们的 IV、他们是否包括 HMAC 或其他身份验证,等等。你需要确切地知道他们是如何实现他们所说的“CRYPT_AES256”的意思的。没有人,这个标准答案。
MQL4 仅支持非常具体的 AES 加密实现,除非您在其他代码中使用正确的设置,否则您将无法实现两个平台之间的兼容性。
具体来说,您需要确保实施以下内容:
- 填充模式:零
- 密码模式:ECB(因此没有 IV)
- 密钥大小:256
- 块大小:128
您还需要记住,在 MQL4 中,encryption/decryption 是一个两阶段过程(到 AES256,然后到 BASE64)。
您可以尝试使用在线 AES encryption/decryption 工具来验证您的结果:The online toolbox