【问题标题】:AES encryption to decryption not outputting correctlyAES加密解密无法正确输出
【发布时间】:2019-04-07 20:22:30
【问题描述】:

嘿,我最难弄清楚如何解密加密文本的顺序。

这是我的草图代码:

#include "AES.h"
#include "base64.h"

AES aes;

void gen_iv(byte  *iv) {
    for (int i = 0 ; i < N_BLOCK ; i++ ) {
        iv[i]= (byte) *(volatile uint8_t *)0x3FF20E44;
    }
}

void setup() {
  Serial.begin(115200);
    Serial.println("\nBooting...");  

    char b64data[2000];
    byte cipher[1000];
    byte iv [N_BLOCK];
    char *encodedFinal;

    Serial.println("Let's encrypt:");

    byte *key = (unsigned char*)"5TGB&YHN7UJM(IK<";
    byte *my_iv = (unsigned char*)"!QAZ2WSX#EDC4RFV";
    char *msg = "{\"data\":{\"value\":300}, \"SEQN\":700 , \"msg\":\"IT WORKS!!\" }";

    //Set the key for AES
    aes.set_key(key, sizeof(key));

    /*
    ==================================================================
    Encoding section
    ==================================================================
    */

    //Encode IV to Base64
    base64_encode(b64data, (char *)my_iv, N_BLOCK);    
    Serial.println("      IV -> Base64: " + String(b64data));
    Serial.println("       Orignal Msg: " + String(msg));

    //Encode message into Base64
    int b64len = base64_encode(b64data, (char *)msg, String(msg).length());
    Serial.println(" Message -> Base64: " + String(b64data));

    // Encrypt into AES256   
    aes.do_aes_encrypt((byte *)b64data, b64len , cipher, key, 256, my_iv);
    Serial.println("Encrypted: " + String(b64data));

    //Encode everything now in Base64
    base64_encode(b64data, (char *)cipher, aes.get_size());
    Serial.println("Encrypted -> Base64: " + String(b64data));
    encodedFinal = (char*)b64data;
    Serial.println("Final encoded: " + String(encodedFinal));

    /*
    ==================================================================
    Decoding section
    ==================================================================
    */

Serial.println();
  Serial.println();
    Serial.println();
      Serial.println();
    //Decoding everything from Base64
    char b64dataDecode[2000];
    byte cipherDecode[1000];

    //Decode from Base64 to Encrypted msg
    base64_decode(b64dataDecode, (char *)encodedFinal, aes.get_size());
    Serial.println(" Base64 -> Encrypted: " + String(b64dataDecode));

    //Decoding from Encrypted
    aes.do_aes_decrypt((byte *)encodedFinal, base64_dec_len(encodedFinal, String(encodedFinal).length()), cipherDecode, key, 256, my_iv);
    Serial.println("Encrypted -> Original Msg: ") + String(encodedFinal);

    Serial.println("Done...");
}

void loop() {
  // put your main code here, to run repeatedly:

}

这是我得到的输出:

Booting...
Let's encrypt:
      IV -> Base64: IVFBWjJXU1gjRURDNFJGVg==
       Orignal Msg: {"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }
 Message -> Base64: eyJkYXRhIjp7InZhbHVlIjozMDB9LCAiU0VRTiI6NzAwICwgIm1zZyI6IklUIFdPUktTISEiIH0=
Encrypted: eyJkYXRhIjp7InZhbHVlIjozMDB9LCAiU0VRTiI6NzAwICwgIm1zZyI6IklUIFdPUktTISEiIH0=
Encrypted -> Base64: sD9f8LnxQrlOvTODLbzXPM5wWMk6+KnpmGiowTtKswGK80+yf9DyHjjiF94TwUpP/1V4f9KsHA7+1oAmBy12Dl8Dvk/ZclFvNeNrXSwCFlU=
Final encoded: sD9f8LnxQrlOvTODLbzXPM5wWMk6+KnpmGiowTtKswGK80+yf9DyHjjiF94TwUpP/1V4f9KsHA7+1oAmBy12Dl8Dvk/ZclFvNeNrXSwCFlU=




 Base64 -> Encrypted: ⸮?_⸮⸮B⸮N⸮3⸮-⸮⸮<⸮pX⸮:⸮⸮⸮h⸮⸮;J⸮⸮⸮O⸮⸮⸮8⸮⸮⸮JO⸮UxҬ⸮ր&
Encrypted -> Original Msg: 
Done...

正如您在上面看到的,解密工作不正常。虽然加密工作得很好(但我认为编码部分没有正确输出,因为它与 Base64 编码相同?)。

帮助解决这个问题会很棒!

【问题讨论】:

  • aes.set_key(key, sizeof(key)); 将使用 byte* 的大小作为长度参数。应该是aes.set_key(key, strlen(key));
  • 并检查返回值。我很确定你会从 set_key 得到 FAILURE ,并且函数取决于那个键。
  • 请选择一种语言,C 或 C++!

标签: c++ c encryption arduino arduino-esp8266


【解决方案1】:

先用key和IV加密,然后编码成base64。解码端,解码base64,用相同的key和IV解密。

请注意,AES 函数会更改 IV,因此如果您在同一函数中进行测试,则必须将其保持为常量并复制到可变变量。

为简单起见,去掉base64部分,尝试加解密:

int msglen = strlen(msg);
int msglen_padded = msglen  + (N_BLOCK - ((msglen - 1) % 16));
byte cipher[msglen_padded];
byte msg_decoded[msglen_padded];
byte iv[N_BLOCK];

aes.iv_inc();
aes.set_IV(my_iv);
aes.get_IV(iv);
aes.do_aes_encrypt(msg, strlen(msg) + 1, cipher, key, 256, iv);//+1 to encrypt null

aes.set_IV(my_iv);
aes.get_IV(iv);
aes.do_aes_decrypt(cipher, cipher_len, msg_decoded, key, 256, iv);

if (aes.get_size())
{
    msg_decoded[aes.get_size() - 1] = 0;
    printf("%s\n", msg);
}

然后您想在 AES 加密/解密之间将 cipher 编码为 base64,然后解码回 cipher

【讨论】:

  • 一种简单、常见且安全的做法是在加密数据前加上 IV,以便可用于解密。 IV确实需要保密。密钥单独提供保密性。
  • 这是真的@zaph 也许这就是提问者在连续调用base64_encode 时的意图。我不熟悉那个 base64 类,似乎第二次调用 base64_encode 只会覆盖数据。此外,它没有使用正确的密钥和 IV,并且 IV 不应在 CBC 模式下重复使用。
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 2012-02-24
  • 2016-09-22
  • 1970-01-01
  • 2012-04-08
相关资源
最近更新 更多