Шифрование AES для дешифрования не выводится правильно

Привет всем, мне очень трудно понять, как сделать порядок дешифрования зашифрованного текста.

Это мой код скетча:

#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));
Ted Lyngmo 04.11.2018 07:12

и проверьте возвращаемые значения. Я почти уверен, что вы получите FAILURE обратно из set_key и функций, зависящих от этого ключа.

Ted Lyngmo 04.11.2018 07:36

Пожалуйста, выберите один язык: C или C++!

Ulrich Eckhardt 04.11.2018 09:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
562
1

Ответы 1

Сначала зашифруйте ключом и IV, а затем закодируйте в base64. На стороне декодера декодируйте base64 и дешифруйте с тем же ключом и 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);
}

Затем вы хотите кодировать cipher в base64 и декодировать обратно в cipher между шифрованием / дешифрованием AES

Простая, распространенная и безопасная практика - добавить к зашифрованным данным префикс IV, чтобы они были доступны для дешифрования. IV действительно должен быть секретным. Секретность обеспечивается одним ключом.

zaph 04.11.2018 09:49

Это правда @zaph Возможно, это было намерением спрашивающего при последовательном вызове base64_encode. Я не знаком с этим классом base64, похоже, второй вызов base64_encode просто перезапишет данные. Также он не использует правильный ключ и IV, и IV не следует повторно использовать в режиме CBC.

Barmak Shemirani 04.11.2018 16:07

Другие вопросы по теме