尝试加密与ESP32(PlatformIO)的通信。 esp_aes_crypt_ecb 在最后一个块上失败

问题描述 投票:0回答:1

我正在尝试将数据从 ESP32 加密到互联网网页。 纯文本长度为 31 个字符,需要 3 个 16 个字符的块。 前两个块加密得很好,但最后一个块失败了。 在 C/C++ 字符串标准规范中,最后一个块以 0 结尾。

请查看我的代码以供参考:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "mbedtls/aes.h"

#include "esp_log.h"
#include "aes/esp_aes.h"
#include "mbedtls/base64.h"

#define ESP_AES_ENCRYPT 1

esp_aes_context aes;

unsigned char key[33] = {'d', 'v', 'i', 'z', 'd', 'u', 'm', 'c', 's', 'm', 'v', 'l', 'v', 'f', 'd', 'v', 'b', 'j', 's', 'v', 'd', 'u', 'i', 'a', 's', 'r', 'u', 'i', 'a', 'e', 'u', 'y', '\0'};
unsigned char encrypted[255] = {0};

void crypto_aes_ecb(char *input){
    static const char *TAG = "CryptTest";
    bool doEncrypt = true;
    uint16_t blockIndex = 0;
    uint16_t inputIndex = 0;
    uint16_t outputIndex = 0;
//    unsigned char input[64] = {'T', 'e', 's', 't', 'i', 'n', 'g', ' ', 'e', 'n', 'c', 'r', 'y', 'p', 't', 'i', 'o', 'n', '.', '.', '.', ' ', 'T', 'e', 's', 't', 'i', 'n', 'g', ' ', 'e', 'n', 'c', 'r', 'y', 'p', 't', 'i', 'o', 'n', '.', '.', '.', '\0'};
    unsigned char inputBlock[16] = {0};
    unsigned char output[17] = {0};
    esp_aes_init(&aes);
    esp_aes_setkey(&aes, (const unsigned char*) key, 256);
    inputIndex = 0;
    while(doEncrypt){
        for (blockIndex = 0; blockIndex < 16; blockIndex++){
            inputBlock[blockIndex] = input[blockIndex + (inputIndex * 16)];
            if(input[blockIndex + (inputIndex * 16)] == '\0'){
                for (; blockIndex < 16; blockIndex++){inputBlock[blockIndex] = 0;}
                doEncrypt = false;
                break;
            }
        }
        inputIndex++;
        inputBlock[16] = '\0';
        ESP_LOGI(TAG, "inputBlock = '%s'", inputBlock);
        esp_aes_crypt_ecb(&aes, ESP_AES_ENCRYPT, (const unsigned char *)inputBlock, output);
        for (blockIndex = 0; blockIndex < 16; blockIndex++){
            encrypted[blockIndex + (outputIndex * 16)] = output[blockIndex];
        }
        outputIndex++;
    }
    ESP_LOGW(TAG, "-----------------------------------------------------------------------------------");
    ESP_LOGW(TAG, "Key     : '%s'", key);
    ESP_LOGW(TAG, "Input   : '%s'", input);
//    ESP_LOGW(TAG, "Output  : '%s'", encrypted);
    ESP_LOG_BUFFER_HEXDUMP(TAG, encrypted, 128, ESP_LOG_WARN);
    esp_aes_free(&aes);
}

void app_main(){
    crypto_aes_ecb("Testing encryption... Testing encryption...");
}

使用在线加密/解密测试器测试 HexDump,它报告“鉴于最终块未正确填充。如果在解密过程中使用错误密钥,可能会出现此类问题。” 测试纯文本,我可以看到最后一个块与我的 ESP32 不同。 知道如何解决这个问题吗?

测试网站:https://www.devglan.com/online-tools/aes-encryption-decryption

Dump from ESP32 : 
ea 99 ca 39 2b 62 58 ce 71 5a 75 62 fe ac b7 f0 29 16 0c 1e 20 f5 ba 6f b0 7e c7 ee 0b eb 3a e3 89 51 f4 84 97 61 4b e8 66 22 78 72 60 0f 3e 2d
Result from web page : 
EA 99 CA 39 2B 62 58 CE 71 5A 75 62 FE AC B7 F0 29 16 0C 1E 20 F5 BA 6F B0 7E C7 EE 0B EB 3A E3 3F 3E 65 3F 78 BA AD 13 AE 74 3E 99 44 1F E1 E5

我尝试过谷歌搜索加密方法,但没有成功。大多数示例都会导致编译错误。 我尝试过 ChatGPT。还会导致编译错误。 他们警告我使用 ECB 进行“不安全”加密。该警告不适用于我。在更新密钥之前,我的 ESP32 只会发送 10-15 个区块。

encryption aes esp32 platformio ecb
1个回答
0
投票

所以 - 我的解决方案,如果有人想要一个可行的示例:

--- ESP32 侧 ---

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "mbedtls/aes.h"

#include "esp_log.h"
#include "aes/esp_aes.h"
#include "mbedtls/base64.h"

#define ESP_AES_ENCRYPT 1

esp_aes_context aes;

unsigned char key[33] = {'d', 'v', 'i', 'z', 'd', 'u', 'm', 'c', 's', 'm', 'v', 'l', 'v', 'f', 'd', 'v', 'b', 'j', 's', 'v', 'd', 'u', 'i', 'a', 's', 'r', 'u', 'i', 'a', 'e', 'u', 'y', '\0'};
unsigned char encoded[1024] = {0};

void crypto_aes_ecb(char *input){
    static const char *TAG = "CryptTest";
    bool doEncrypt = true;
    uint16_t blockIndex = 0;
    uint16_t inputIndex = 0;
    uint16_t outputIndex = 0;
    uint16_t encryptedLength = 0;
    size_t encodedLength = 0;
    unsigned char inputBlock[16] = {0};
    unsigned char outputBlock[17] = {0};
    unsigned char encrypted_raw[1024] = {0};
    esp_aes_init(&aes);
    esp_aes_setkey(&aes, (const unsigned char*) key, 256);
    inputIndex = 0;
    while(doEncrypt){
        for (blockIndex = 0; blockIndex < 16; blockIndex++){
            inputBlock[blockIndex] = input[blockIndex + (inputIndex * 16)];
            if(input[blockIndex + (inputIndex * 16)] == '\0'){
                for (; blockIndex < 16; blockIndex++){inputBlock[blockIndex] = '\0';}
                doEncrypt = false;
                break;
            }
        }
        if(input[blockIndex + (inputIndex * 16)] == '\0'){doEncrypt = false;}
        inputBlock[16] = '\0';
        ESP_LOGI(TAG, "inputBlock = '%s'", inputBlock);
        esp_aes_crypt_ecb(&aes, ESP_AES_ENCRYPT, (const unsigned char *)inputBlock, outputBlock);
        for (blockIndex = 0; blockIndex < 16; blockIndex++){
            encrypted_raw[blockIndex + (outputIndex * 16)] = outputBlock[blockIndex];
        }
        encryptedLength = blockIndex + (outputIndex * 16);
        inputIndex++;
        outputIndex++;
    }
//    encodedLength = mbedtls_base64_encode(encrypted_raw, encryptedLength, encoded, sizeof(encoded));
    mbedtls_base64_encode((unsigned char*)encoded, sizeof(encoded), &encodedLength, encrypted_raw, encryptedLength);
    encoded[encodedLength] = '\0';
    ESP_LOGW(TAG, "-----------------------------------------------------------------------------------");
    ESP_LOGI(TAG, "Key     : '%s'", key);
    ESP_LOGI(TAG, "Input   : '%s'", input);
    ESP_LOGI(TAG, "Output  : '%s'", encoded);
    esp_aes_free(&aes);
}

void app_main(){
    crypto_aes_ecb("Testing encryption... Testing encryption...");
}

--- 结果---

I (325) CryptTest: -----------------------------------------------------------------------------------
I (335) CryptTest: Key     : 'dvizdumcsmvlvfdvbjsvduiasruiaeuy'
I (335) CryptTest: Input   : 'Testing encryption... Testing encryption...'
I (345) CryptTest: Output  : '6pnKOStiWM5xWnVi/qy38CkWDB4g9bpvsH7H7gvrOuOJUfSEl2FL6GYieHJgDz4t'

--- PHP 端 ---

<?php
    $cryptoKey = "dvizdumcsmvlvfdvbjsvduiasruiaeuy";
    $base64 = "6pnKOStiWM5xWnVi/qy38CkWDB4g9bpvsH7H7gvrOuOJUfSEl2FL6GYieHJgDz4t";
    $intRes = openssl_decrypt($base64, 'AES-256-ECB', $cryptoKey,  OPENSSL_ZERO_PADDING);
    $decrypted = rtrim($intRes, "\0");
    echo "<html>\n<body>\n";
    echo "Key       : '" . $cryptoKey . "'<br />\n";
    echo "Input     : '" . $base64 . "'<br />\n";
    echo "Decrypted : '" . $decrypted . "'<br />\n";
    echo "</body>\n</html>\n";
?>

--- 结果---

Key : 'dvizdumcsmvlvfdvbjsvduiasruiaeuy'
Input : '6pnKOStiWM5xWnVi/qy38CkWDB4g9bpvsH7H7gvrOuOJUfSEl2FL6GYieHJgDz4t'
Decrypted : 'Testing encryption... Testing encryption...'
© www.soinside.com 2019 - 2024. All rights reserved.