AES 128在Arduino ESP8266和在线工具中具有不同的结果

时间:2019-03-11 08:17:48

标签: encryption arduino aes

我想通过AES 128 CBC加密文本,但是在Arduino和在线工具中结果不同。我尝试了不同的Arduino库,但仍然存在相同的问题。 我在arduino中的代码如下。

#include <Crypto.h>
#include <ebase64.h>

#define BLOCK_SIZE 16

byte key[BLOCK_SIZE] = {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
byte iv[BLOCK_SIZE] = {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};

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];

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];
base64_encode(encoded, (char*)enciphered, encrypted_size);

strcpy(output, encoded);
}

void decrypt(char* enciphered, char* output, int length)
{
length = length + 1; //re-adjust
int decodedLen = base64_dec_len(enciphered, length);
char decoded[length];

Serial.println(enciphered);
base64_decode(decoded, enciphered, length);
bufferSize(enciphered, length);
byte deciphered[length];
AES aesDecryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_DECRYPT);

aesDecryptor.process((uint8_t*)decoded, deciphered, length);
strcpy(output, (char*)deciphered);
}

void setup()
{
Serial.begin(115200);
while (!Serial) {
; //wait
}

char plain_text[] = "Now is the time ABCDABC";

// encrypt
int length = 0;
bufferSize(plain_text, length);
Serial.println(length);
char encrypted[length];
encrypt(plain_text, encrypted, length);

Serial.println(encrypted);

// decrypt

length = strlen(encrypted);
char decrypted[length];
decrypt(encrypted, decrypted, length);

Serial.println(decrypted);
}
void loop()
{
}

键和IV:

{0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};

{'0','0','0','0','0','0','0','0','0','0','0','0 ','0','0','0','0'};

文本:“现在是ABCDABC的时间了”;

加密的是

1a7OeiH628V7IIoLU6 + 3n70Dzp6FBQjlGPxSwnuXdzo =

和AES在线工具。 [https://www.devglan.com/online-tools/aes-encryption-decryption]

键:0000000000000000

IV:0000000000000000

文字:现在是ABCDABC的时间

我正在网上加密,结果是

1a7OeiH628V7IIoLU6 + 3n7ILev6IwcZYVNLalS / TBEg =

所以我不能互相解密。有人可以帮助我吗?非常感谢!

1 个答案:

答案 0 :(得分:1)

似乎a crypto library的作者比执行此类专长的“在线工具”的作者更加无知:

   /**
     * Either encrypt or decrypt [in] and store into [out] for [length] bytes, applying padding as needed
     * 
     * Note: the length must be a multiple of 16 bytes
     */
    void process(const uint8_t *in, uint8_t *out, int length);

现在没有指定使用哪个填充,也没有指定如何删除。此外,显然输入不应该总是16的倍数,这没有任何意义。

但是,可以使用不带填充的解密来恢复明文:

4e6f77206973207468652074696d6520414243444142430020000000feefeffe
4e6f77206973207468652074696d652041424344414243090909090909090909
 N o w   i s   t h e   t i m e   A B C D A B C

第一个是您的加密。显然,它根本没有显示正确的填充。它是一个零字节,一个02字节,然后是一个零,后跟feefeffe,这看起来非常像检测未初始化内存的方法。在线库使用PKCS#7兼容的填充。

在查看代码时,对我的第一个想法是在声明包含密文的数组时错了:

byte enciphered[length];

如果密文大小由于填充而扩展了纯文本大小,显然这是不正确的。因此,那里可能有缓冲区溢出。但是,即使对于最后一个块,您仍然会取回原始的纯文本,因此该库也必须出错。

故事的寓意:不要在GitHub上使用可怕的单人库。图书馆需要进行测试,并拥有一支团队,使其对加密足够可信。