Строка или беззнаковый символ для uint8_t
Я пытаюсь сохранить строку в EEPROM радиостанции ESP8266, а затем прочитать ее обратно, прежде чем зашифровать данные (в конечном итоге я хотел бы сохранить зашифрованные данные, но сейчас я упрощаю ситуацию). Вот исходный код:
#include <Arduino.h>
extern "C"
{
#include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Номер слота ключа
uint8_t KEY_SLOT = (uint8_t)9;
ATCAIfaceCfg cfg;
ATCA_STATUS status;
void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
byte len = strToWrite.length();
EEPROM.write(addrOffset, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
}
}
String readStringFromEEPROM(int addrOffset)
{
int newStrLen = EEPROM.read(addrOffset);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(addrOffset + 1 + i);
}
data[newStrLen] = '\0';
return String(data);
}
void setup()
{
Serial.begin(74880);
// Инициализируем конструктор библиотеки
cfg.iface_type = ATCA_I2C_IFACE; // Тип связи -> режим I2C
cfg.devtype = ATECC608A; // Тип чипа
cfg.atcai2c.slave_address = 0X30; // I2C-адрес платы Adafruit Breakout Board
cfg.atcai2c.bus = 1;
cfg.atcai2c.baud = 100000;
cfg.wake_delay = 1500; // Задержка пробуждения (1500 мс)
cfg.rx_retries = 20;
atca_trace_config(stdout);
}
void loop()
{
ATCA_STATUS status = atcab_init(&cfg);
if (status != ATCA_SUCCESS)
{
Serial.println(F("atcab_init() failed : Code -> 0x"));
Serial.println(status, HEX);
}
writeStringToEEPROM(0, "test");
String retrievedString = readStringFromEEPROM(0);
uint8_t plaintext = atoi(retrievedString.substring(1,3).c_str());
uint8_t iv[IV_LENGTH_CBC];
uint8_t cypherdata[sizeof(plaintext)];
Serial.println("Beginning of the encryption !");
status = aes_cbc_encrypt(&cfg, plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
if (status == ATCA_SUCCESS)
{
Serial.println("encrypted");
}
else
{
// См. файл atca_status.h для ошибки кода
Serial.print(F("Impossible do the encryption | Code Error 0x"));
Serial.println(status, HEX);
return;
}
}
и вот сообщение об ошибке:
РЕДАКТИРОВАНИЕ**: Обнаружил, что кнопка «Сохранить в EEPROM» часть моего кода не работала, поэтому я это исправил. Вот новый код:
#include <Arduino.h>
extern "C"
{
#include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Номер слота ключа
uint8_t KEY_SLOT = (uint8_t)9;
ATCAIfaceCfg cfg;
ATCA_STATUS status;
void setup()
{
Serial.begin(74880);
// Инициализируем конструктор библиотеки
cfg.iface_type = ATCA_I2C_IFACE; // Тип связи -> режим I2C
cfg.devtype = ATECC608A; // Тип чипа
cfg.atcai2c.slave_address = 0X30; // I2C-адрес платы Adafruit Breakout Board
cfg.atcai2c.bus = 1;
cfg.atcai2c.baud = 100000;
cfg.wake_delay = 1500; // Задержка пробуждения (1500 мс)
cfg.rx_retries = 20;
atca_trace_config(stdout);
}
void loop()
{
ATCA_STATUS status = atcab_init(&cfg);
if (status != ATCA_SUCCESS)
{
Serial.println(F("atcab_init() failed : Code -> 0x"));
Serial.println(status, HEX);
}
uint addr = 0;
struct
{
uint val = 0;
char str[16] = "";
} data;
EEPROM.begin(512);// фиксируем 512 байт флэш-памяти ESP8266 (для эмуляции "EEPROM")
strcpy(data.str,"test");
EEPROM.put(addr,data);
EEPROM.commit();
EEPROM.get(addr,data);
Serial.println(String(data.str));
uint8_t plaintext = atoi(data.str);
//uint8_t Plaintext[16] = "тест";
uint8_t iv[IV_LENGTH_CBC];
uint8_t cypherdata[sizeof(plaintext)];
uint8_t decryptdata[sizeof(plaintext)];
Serial.println("Beginning of the encryption !");
status = aes_cbc_encrypt(&cfg, &plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
if (status == ATCA_SUCCESS)
{
Serial.println("encrypted");
status = aes_cbc_decrypt(&cfg, cypherdata, sizeof(cypherdata), iv, decryptdata, KEY_SLOT);
if (status == ATCA_SUCCESS)
{
Serial.print("Decrypted text is : ");
for (size_t i = 0; i < sizeof(decryptdata); i++)
{
Serial.print((char)decryptdata[i]);
}
Serial.println("");
}
}
else
{
// См. файл atca_status.h для ошибки кода
Serial.print(F("Impossible do the encryption | Code Error 0x"));
Serial.println(status, HEX);
return;
}
delay(1000);
}
Теперь я вижу это в терминале (при компиляции ошибок нет!):
encrypted
ERROR Decrypt : ATCA_BAD_PARAMI2C send 1 bytes to addr 0x30: 01
Когда я меняю (функция aes_cbc_encrypt ожидает длину 16)
sizeof(plaintext)
в
16
Я вижу:
Decrypted text is : ␀␀␀␀␀␀␀␀l��?���?
Когда я доказал, что часть моего кода, шифрующая/дешифрующая, работает, вот что "открытый текст" было:
uint8_t plaintext[16] = "test";
@PhippsTech, 👍0
Обсуждение1 ответ
Лучший ответ:
Функция atoi()
пытается интерпретировать строку как текстовый
представление числа, записанного в десятичной форме. Например, atoi("42")
возвращает целое число 42. Здесь:
uint8_t plaintext = atoi(data.str);
Вы просите его интерпретировать "test"
, который не похож на
число. В таком случае atoi()
возвращает ноль. Я не знаю, что было
ваше намерение, но, вероятно, это было не это.
Далее у вас есть
uint8_t cypherdata[sizeof(plaintext)];
uint8_t decryptdata[sizeof(plaintext)];
Учитывая, что plaintext
представляет собой один байт, его длина равна единице. Таким образом, это
объявление двух массивов длиной один. Опять же, вы, вероятно, что-то имели в виду
еще.
Из вашего комментария я понял, что вы хотите, чтобы plaintext
представлял
строку "test"
как массив uint8_t
.
Поскольку и char
, и uint8_t
представляют байты, преобразование не выполняется.
нужный. Вы можете просто использовать адрес исходного массива char
и
«представьте», что это адрес массива uint8_t
:
uint8 *plaintext = (uint8_t *) data.str;
Я просто храню строку «test» в EEPROM, а затем преобразую ее в uint, чтобы ее можно было поместить в функцию aes_cbc_encrypt. Я изменил команду atoi на toInt и все равно получаю то же самое. Я отредактирую сообщение, чтобы объяснить, что в исходном примере aes_ebc_encrypt я использовал uint8 Plaintext[16] = "test";
и это работало., @PhippsTech
в этом есть смысл. Это сработало, и я просто поставил 16 для размера (открытый текст). На данный момент это должно сработать. Спасибо!, @PhippsTech
- Как читать и записывать EEPROM в ESP8266
- Преобразование строки в IP-адрес
- Как составить URL-адрес HTTP-запроса GET с параметрами ключ/значение
- Spiffs против Eeprom на esp8266
- В ESP8266 EEPROM сохраненные данные отличаются, когда я пытаюсь их прочитать
- Какова цель F() и FPSTR() в ESP8266WebServer -> FSBrowser?
- Как исправить код утечки памяти в ESP8266/NodeMCU, вызванный концентрацией строк?
- Значение неинициализированной EEPROM в ESP8266
Пожалуйста, не используйте текст как изображение. Вы можете скопировать сообщение об ошибке в виде текста в свой вопрос и отформатировать его так же, как код., @chrisl
Функция ожидает указатель на данные. Попробуйте передать его по ссылке как
& Plaintext
. Хотя я не уверен, действительно ли ты этого хочешь. Имя переменнойplaintext
предполагает, что это должен быть текст. Хотя это просто число (8-битное целое число без знака), @chrislОпять же, вы, кажется, думаете, что «открытый текст» содержит текстовое сообщение. Это не.
sizeof(plaintext)
всегда равен 1, посколькуplaintext
имеет только 1 байт. Вы шифруете один «символ», хотя на самом деле это не символ, а двоичное представление числа. Для меня не имеет никакого смысла шифровать один байт. Почему вы используетеatoi()
при назначенииplaintext
? Закомментированная строка предполагает, что это должен быть массив, содержащий строку ac., @chrislКрисл, В другом рабочем коде у меня было uint8_t Plaintext[16] = "тест"; Без бита EEPROM это сработало. Когда я пытаюсь заменить «test» на data.str, компиляция выдает ошибку. Если мне нужно вызвать что-то кроме открытого текста, хорошо. Я специалист по аппаратному обеспечению, который изо всех сил старается стать лучше в прошивке, поэтому извините, если я не разбираюсь в простых вещах., @PhippsTech