当前位置: 首页 > 知识库问答 >
问题:

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

凌征
2023-03-14

我想在Go中使用AES-256加密一个字符串,无需任何GCM处理,以与MQL4进行比较。当我试图加密特殊字符或数字时,我会遇到问题。我应该以某种方式预处理我的明文吗?我是新来的,所以任何帮助都将不胜感激;我的代码在这个解释下面。

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

如果我试图加密“这是一个秘密;1234”,密文在末尾有一组零,当我解密时,我只得到“这是一个秘密”。MQL4中类似的密文在末尾没有零,并且正确解密。

如果我尝试只加密“1234”,我会得到生成错误,源于“crypto/aes(*aesCipherAsm).encrypt(0xc000c43c0,0xc000ac058,0x4,0xc000ac070,0x4,0x8)C:/Program Files/Go/src/crypto/aes/cipher\u 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)
        }
    }

共有2个答案

帅雅逸
2023-03-14

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

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

  • 填充模式:零
  • 密码模式:ECB(因此无IV)
  • 按键大小:256
  • 区块大小:128

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

您可以尝试在线AES加密/解密工具来验证您的结果

方韬
2023-03-14

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

文本中的特定字符是不相关的。加密是对原始字节而不是字母执行的。

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

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

 类似资料:
  • 字符串像这里一样用php加密。可以用这个用参数解密:Rijndael-256,ECB,Base64。但是我的ActionScript代码无法解密它: 更新: “它无法解密”意味着我弄错了纯文本。 在php中,明文首先由aes-256-ecb加密。然后由Base64编码。在ActionScript中,这些步骤以相反的顺序进行。 UPD2: 编码-解码测试: 在 停止后的输出是: 更新3: 它适用于P

  • 问题内容: 我有一个来自CryptoJS的加密AES-256字符串,带有密码短语。我需要用Java对其解密,但无法弄清楚该怎么做。似乎需要IV,密钥和盐来解密,就像在CryptoJS主页中一样,加密的数据已经包含所有这些内容,并且CryptoJS可以某种方式从加密的输入中解析出它们。 有人知道该怎么做吗?我已经看到了很多有关CryptoJS的示例-Java加密/解密,但大多数都使用硬编码的IV /

  • 我有一个加密的AES-256字符串从CryptoJS与密码。我需要Java解密,但不知道怎么做。似乎你需要IV、key和盐来解密,就像在CryptoJS主页一样,加密数据已经包含了所有这些数据,CryptoJS可以以某种方式将它们从加密输入中解析出来。 有人知道怎么做吗?我已经看到了很多关于CryptoJS的例子——Java加密/解密,但大多数都使用硬编码的IV/密钥,或者只是从CryptoJS端

  • 我在这个网站上用AES-256加密一个虚拟字符串: https://www.devglan.com/online-tools/aes-encryption-decryption 具有以下参数: null 当我尝试用OpenSSL从命令行解密它时: 我得到这个错误:

  • 我目前正在使用Fernet加密,它使用AES 128密钥。然而,我的客户要求使用AES 256。我对密码学不是很熟悉,但以下是我迄今为止的理解。 Fernet需要一个分为两半的256位密钥。前半部分是签名密钥,第二部分是加密密钥。由于它们的长度为128位,因此是AES 128。 将输入键加倍并修改下面的实现以获得AES 256是否足够?

  • 问题内容: 我有下面的Java代码来加密使用64个字符的密钥的字符串。我的问题是这将是AES-256加密吗? 以下是结合了divanov和laz建议的代码。 问题答案: 是的,它将是64个字符,即32个字节和256位,并且256位的任何序列都可以用作AES-256密钥。 我建议您使用DatatypeConverter.parseHexBinary(或您选择的库中的类似实用程序)将十六进制字符串转换