首页 > 解决方案 > 如何使用 AES-256 加密特殊字符或数字?

问题描述

我想在没有任何 GCM 处理的情况下使用 AES-256 加密 Go 中的字符串,以与 MQL4 进行比较。我在尝试加密特殊字符或数字时遇到问题。我应该以某种方式预处理我的明文吗?我是 Go 新手,因此我们将不胜感激;我的代码低于这个解释。

如果我加密明文“这是一个秘密”,然后解密密文(编码为十六进制),我会得到相同的结果(即“这是一个秘密”)。pt 是下面代码中明文的变量名。

如果我尝试加密“这是一个秘密;1234”,密文末尾有一组零,当我解密时,我只会得到“这是一个秘密”。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)
        }
    }

标签: goencryptionaesmql4

解决方案


您正在此处创建原始 AES 加密器。AES 只能精确加密 16 字节的明文,产生精确的 16 字节密文。您的第一个示例"This is a secret"正好有 16 个字节长,所以它按预期工作。你的第二个例子太长了。只有前 16 个字节被加密。第三个示例太短了,您可能会遇到未初始化的内存。

文本中的特定字符无关紧要。加密是在原始字节上执行的,而不是字母。

为了加密更大(或更小)的文本块,您需要在 AES 之上使用块密码模式。常见的模式有 GCM、CBC 和 CTR,但还有很多其他模式。在大多数情况下,当有人说“AES”而没有任何限定词时,他们的意思是 AES-CBC。(GCM 变得越来越流行,它是一种很棒的模式,但它还没有流行到人们认为的程度。)

我对 MQL4 一无所知,但我假设您正在尝试重新实现CryptEncode?我没有看到任何关于他们如何进行加密的文档。您需要知道他们使用什么模式,他们如何派生他们的密钥,他们如何生成(并可能编码)他们的 IV,他们是否包括 HMAC 或其他身份验证等等。您需要确切地知道他们如何实现“CRYPT_AES256”所指的一切。对此没有一个标准的答案。


推荐阅读