[英]C++/Arduino: strcpy(), strncpy() and memcpy() on unsigned char not working
I am trying to implement AES-128 and AES-256 on an Arduino (Adafruit Feather M0, for any other people using SAMD21 processors!).我正在尝试在 Arduino(Adafruit Feather M0,对于使用 SAMD21 处理器的任何其他人!)上实现AES-128和 AES-256。 The encryption and decryption is working, but I am unable to “save” the encrypted value.
加密和解密工作,但我无法“拯救”的加密值。 I believe the example passes a pointer for a char array to
void encrypt()
, but when usingstrcpy
,strncpy
ormemcpy
to copy over the value from the local char array to the one back in my loop()
, the value never actually gets copied over.我相信该示例将 char 数组的指针传递给
void encrypt()
,但是当使用strcpy
、strncpy
或memcpy
将本地字符数组中的值复制到我的loop()
中的值时,该值实际上从未获得复制过来。
Note that the hang only occurs in the void encrypt()
method and I wonder if it is due to the encode_base64
line where the example code is casting the data as unsigned char*
.请注意,挂起仅发生在
void encrypt()
方法中,我想知道这是否是由于encode_base64
行导致示例代码将数据转换为unsigned char*
。 I've been able to use strcpy
, strncpy
and memcpy
successfully in void decrypt()
so all I can think is that it's the unsigned char type.我已经能够在
void decrypt()
成功使用strcpy
、 strncpy
和memcpy
,所以我能想到的是它是 unsigned char 类型。
Though according to this a char is ultimately treated like an unsigned char in standard libraries, which I assume that the strcpy
function is part of the standard string library and not something special to Arduino.尽管根据this ,char最终被视为标准库中的无符号char,但我认为
strcpy
函数是标准字符串库的一部分,而不是Arduino的特殊内容。
I am very new to C/C++ and am nowhere near an expert.我对 C/C++ 很陌生,离专家还差得很远。 I am not quite sure how to get around this issue so I am hoping someone can point me in the right direction.
我不太确定如何解决这个问题,所以我希望有人能指出我正确的方向。
Code (I included links to the libraries at the top for each #include
)代码(我在每个
#include
的顶部包含了指向库的链接)
#include <Crypto.h> // https://github.com/intrbiz/arduino-crypto
#include <base64.hpp> // https://github.com/Densaugeo/base64_arduino
#define BLOCK_SIZE 16
uint8_t key[BLOCK_SIZE] = { 0x1C,0x3E,0x4B,0xAF,0x13,0x4A,0x89,0xC3,0xF3,0x87,0x4F,0xBC,0xD7,0xF3, 0x31, 0x31 };
uint8_t iv[BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char plain_text[] = "1234567890ABCDEF1234567890ABCDEF";
void bufferSize(char* text, int &length)
{
int i = strlen(text);
int buf = round(i / BLOCK_SIZE) * BLOCK_SIZE;
length = (buf <= i) ? buf + BLOCK_SIZE : length = buf;
}
void encrypt(char* plain_text, char* output, int length)
{
byte enciphered[length];
// RNG::fill(iv, BLOCK_SIZE); // Using fixed test iv
AES aesEncryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_ENCRYPT);
aesEncryptor.process((uint8_t*)plain_text, enciphered, length);
int encrypted_size = sizeof(enciphered);
char encoded[encrypted_size];
encode_base64(enciphered, encrypted_size, (unsigned char*)encoded);
Serial.print("void encrypt :: Encrypted: ");
Serial.println(encoded);
// strcpy(output, encoded); //- Hangs
// strncpy(output, encoded, strlen((char*)encoded)); - Hangs
// memcpy(output, encoded, strlen((char*)encoded)); - Hangs
}
void decrypt(char* enciphered, char* output, int length)
{
length = length + 1; //re-adjust
char decoded[length];
decode_base64((unsigned char*)enciphered, (unsigned char*)decoded);
bufferSize(enciphered, length);
byte deciphered[length];
AES aesDecryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_DECRYPT);
aesDecryptor.process((uint8_t*)decoded, deciphered, length);
Serial.print("void decrypt :: Decrypted: ");
Serial.println((char*)deciphered);
strcpy(output, (char*)deciphered);
// strncpy(output, (char*)deciphered, strlen((char*)deciphered));
// memcpy(output, (char*)deciphered, strlen((char*)deciphered));
}
void setup() {
Serial.begin(115200);
while (!Serial) {
; //wait
}
Serial.println("AES128-CBC Test :: Starting...");
Serial.print("Plaintext input "); Serial.println(plain_text);
}
void loop() {
Serial.println(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \n");
// Encrypt
int length = 0;
bufferSize(plain_text, length);
// Serial.print("Buffer length: ");
// Serial.println(length);
char encrypted[128];
encrypt(plain_text, encrypted, length);
// Serial.println("");
Serial.print("RETURNED Encrypted Value: ");
Serial.println(encrypted);
// Decrypt
length = 128; // WAS strlen(encrypted);
char decrypted[length];
char testEncryptedPayload[] = "pJUX0k/h/63Jywlyvn7vTMa9NdJF9Mz6JOB1T1gDMq+0NUkNycBR780kMvCYILGP"; // Added for testing purposes
decrypt(testEncryptedPayload, decrypted, length);
Serial.print("RETURNED Decrypted Value: ");
Serial.println(decrypted);
delay(5000);
}
/*
EXAMPLE FROM DOCUMENTATION => loop()
void loop() {
char plain_text[] = "1234567890ABCDEF1234567890ABCDEF";
// Encrypt
int length = 0;
bufferSize(plain_text, length);
char encrypted[length];
encrypt(plain_text, encrypted, length);
Serial.println("");
Serial.print("Encrypted: ");
Serial.println(encrypted);
// Decrypt
length = strlen(encrypted);
char decrypted[length];
decrypt(encrypted, decrypted, length);
Serial.print("Decrypted: ");
Serial.println(decrypted);
delay(5000);
}
*/
Sample Output:示例输出:
AES128-CBC Test :: Starting...
Plaintext input 1234567890ABCDEF1234567890ABCDEF
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
void encrypt :: Encrypted: pJUX0k/h/63Jywlyvn7vTMa9NdJF9Mz6JOB1T1gDMq/eQVoPjf/UYv+9SuzV8LQa
RETURNED Encrypted Value: L
void decrypt :: Decrypted: 1234567890ABCDEF1234567890ABCDEF
RETURNED Decrypted Value: 1234567890ABCDEF1234567890ABCDEF
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
I have not run the code, but in general it "hangs" with the M0 and has all been memory-related in my experience.我还没有运行代码,但总的来说,它与 M0 一起“挂起”,并且在我的经验中都与内存相关。
These two lines:这两行:
// strncpy(output, encoded, strlen((char*)encoded)); - Hangs
// memcpy(output, encoded, strlen((char*)encoded)); - Hangs
Perhaps what is actually failing is the strlen
.也许真正失败的是
strlen
。 Maybe encoded
is not NULL terminated?也许
encoded
不是NULL 终止? Can you try with the actual length?你可以试试实际长度吗? (for example,
memcpy(output, encoded, encoded_length);
) (例如,
memcpy(output, encoded, encoded_length);
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.