如何使用AES-256加密特殊字符或数字?

huangapple go评论78阅读模式
英文:

How do I encrypt special characters or numbers using AES-256?

问题

我将为您翻译以下内容:

我想使用AES-256在Go中加密一个字符串,不进行任何GCM处理,以便与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() {

	// 密钥
	key := "thisis32bitlongpassphraseimusing"

	// 明文
	pt := "This is a secret"
	//	pt := "This is a secret; 1234" // 密文末尾有零
	//	pt := "1234" // 无法构建

	c := EncryptAES([]byte(key), pt)

	// 明文
	fmt.Println(pt)

	// 密文
	fmt.Println(c)

	// 解密
	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)
	}
}

希望对您有所帮助!

英文:

I would like to encrypt a string in Go using AES-256, without any GCM processing, to compare against MQL4. I encounter issues when I try to encrypt special characters or numbers. Should I be pre-processing my plaintext somehow? I am new to Go so any help would be appreciated; my code is below this explanation.

If I encrypt the plaintext "This is a secret" and then decrypt the ciphertext (encoded to hex), I get the same result (i.e. "This is a secret"). pt is the variable name of the plaintext in the code below.

If I try to encrypt "This is a secret; 1234", the ciphertext has a group of zeroes at the end, and when I decrypt I only get "This is a secret". Similar ciphertext in MQL4 does not have zeroes at the end and decrypts correctly.

If I try to encrypt only "1234", I get build errors, stemming from "crypto/aes.(*aesCipherAsm).Encrypt(0xc0000c43c0, 0xc0000ac058, 0x4, 0x4, 0xc0000ac070, 0x4, 0x8)
C:/Program Files/Go/src/crypto/aes/cipher_asm.go:60 +0x125"

Here is my code:


    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)
    	}
    }

答案1

得分: 4

你在这里创建了一个原始的AES加密器。AES只能精确地加密16个字节的明文,产生16个字节的密文。你的第一个例子“这是一个秘密”恰好是16个字节长,所以它按预期工作。你的第二个例子太长了。只有前16个字节被加密。第三个例子太短,你可能会遇到未初始化的内存。

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

为了加密更大(或更小)的文本块,你需要在AES之上使用块密码模式。常见的模式有GCM、CBC和CTR,但还有许多其他模式。在大多数情况下,当有人说“AES”而没有任何限定词时,他们指的是AES-CBC。(GCM变得越来越流行,它是一个很好的模式,但它还不太流行,尚未被广泛接受。)

我对MQL4一无所知,但我猜你是在尝试重新实现CryptEncode?我没有看到关于他们如何进行加密的任何文档。你需要知道他们使用的模式、如何派生他们的密钥、如何生成(可能是编码)他们的IV、是否包含HMAC或其他认证,以及更多。你需要确切地知道他们如何实现他们所说的“CRYPT_AES256”。这没有一个标准答案。

英文:

You're creating a raw AES encryptor here. AES can only encrypt precisely 16 bytes of plaintext, producing exactly 16 bytes of cipher text. Your first example "This is a secret" is exactly 16 bytes long, so it works as expected. Your second example is too long. Only the first 16 bytes are being encrypted. The third example is too short and you're likely running into uninitialized memory.

The specific characters in your text are irrelevant. Encryption is performed on raw bytes, not letters.

In order to encrypt larger (or smaller) blocks of text, you need to use a block cipher mode on top of AES. Common modes are GCM, CBC, and CTR, but there are many others. In most cases, when someone says "AES" without any qualifier, they mean AES-CBC. (GCM is becoming much more popular, and it's a great mode, but it's not so popular that it's assumed quite yet.)

I don't know anything about MQL4, but I assume you're trying to reimplement CryptEncode? I don't see any documentation on how they do the encryption. You need to know what mode they use, how they derive their key, how they generate (and possibly encode) their IV, whether they include an HMAC or other auth, and more. You need to know exactly how they implement whatever they mean by "CRYPT_AES256." There is no one, standard answer to this.

答案2

得分: 4

MQL4仅支持AES加密的特定实现,除非您在其他代码中使用正确的设置,否则无法实现两个平台之间的兼容性。

具体而言,您需要确保实现以下内容:

  • 填充模式:零填充
  • 密码模式:ECB(无需初始化向量)
  • 密钥大小:256位
  • 块大小:128位

您还需要记住,在MQL4中,加密/解密是一个两阶段的过程(先AES256,然后BASE64)。

您可以尝试在线AES加密/解密工具来验证您的结果,该工具在此处提供:在线工具箱

英文:

MQL4 only supports a very specific implementation of AES encryption and unless you use the correct settings in your other code you will not achieve compatibility between the two platforms.

Specifically you need to ensure the following are implemented:

  • Padding Mode: Zeros
  • Cipher Mode: ECB (so no IV)
  • KeySize: 256
  • BlockSize: 128

You also need to remember in MQL4 that encryption/decryption is a two stage process (to AES256 then to BASE64).

You can try the online AES encryption/decryption tool to verify your results available here: The online toolbox

huangapple
  • 本文由 发表于 2021年5月28日 20:44:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/67739093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定