首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ESP8266 AES加密-解密

ESP8266 AES加密-解密
EN

Stack Overflow用户
提问于 2017-01-30 04:20:23
回答 3查看 8.3K关注 0票数 0

我确信我做错了解码和解密,但我不知道具体是什么。

代码语言:javascript
复制
#include "AES.h"
#include "Base64.h"

AES aes;

// Our AES key. Note that is the same that is used on the Node-Js side but as hex bytes.
byte key[] = {0x7e, 0x4e, 0x42, 0x38, 0x43, 0x63, 0x4f, 0x4c, 0x23, 0x4a, 0x21, 0x48, 0x3f, 0x7c, 0x59, 0x72};

// The unitialized Initialization vector
byte iv[N_BLOCK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

// Our message to encrypt. Static for this example.
String msg = "{\"data\":{\"value\":300}, \"SEQN\":700 , \"msg\":\"IT WORKS!!\" }";

uint8_t generate_random_unit8()
{
  uint8_t really_random = *(volatile uint8_t *)0x3FF20E44;
  return really_random;
}

// Generate a random initialization vector
void generate_iv(byte *vector)
{
  for (int i = 0; i < N_BLOCK; i++)
  {
    vector[i] = (byte)generate_random_unit8();
  }
}

void encrypt()
{
  char b64data[200];
  byte cipher[1000];
  byte iv[N_BLOCK];

  generate_iv(iv);

  base64_encode(b64data, (char *)iv, N_BLOCK);
  String IV_base64 = String(b64data);
  Serial.println(" IV b64: " + IV_base64);

  int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length());

  Serial.println(" The lenght is:  " + String(b64len));

  // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding
  aes.do_aes_encrypt((byte *)b64data, b64len, cipher, key, 128, iv);

  Serial.println("Cipher size: " + String(aes.get_size()));

  base64_encode(b64data, (char *)cipher, aes.get_size());
  Serial.println("Encrypted data in base64: " + String(b64data));

  decrypt(b64data, IV_base64, aes.get_size());
}

void decrypt(String b64data, String IV_base64, int size)
{
  char data_decoded[200];
  char iv_decoded[200];
  byte out[200];
  char temp[200];
  b64data.toCharArray(temp, 200);
  base64_decode(data_decoded, temp, b64data.length());
  IV_base64.toCharArray(temp, 200);
  base64_decode(iv_decoded, temp, IV_base64.length());
  aes.do_aes_decrypt((byte *)data_decoded, size, out, key, 128, (byte *)iv_decoded);
  char message[msg.length()];
  base64_decode(message, (char *)out, b64data.length());
  printf("Out %s \n", message);
}

void setup_aes()
{
  aes.set_key(key, sizeof(key)); // Get the globally defined key
}

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  encrypt();
  delay(1000);
}

解码后的消息应该是{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!"。然而,我得到了{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }�������������������������。我会假设字符长度不正确?

EN

回答 3

Stack Overflow用户

发布于 2017-01-30 04:32:35

如果你编码,你应该用\0结束字符串,所以在解码的数据中,\0也在那里,printf可以正确地在\0结束。

修复方法是int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length()+1);,这样可以确保包含隐式\0字节。编译器自动将其添加到msg字符串中。

试试看!

票数 1
EN

Stack Overflow用户

发布于 2017-08-06 12:00:06

最近我自己也遇到了同样的问题,我花了几个小时试图解决这个问题。Ivanov,关于编码数据的长度,你有一个很好的观点。主要的问题是,当AES加密功能创建额外的填充而解密功能不能移除它时。

这与字符串的null终止或缺少终止符的事实无关。这个问题实际上是通过简单地省略解密字符串中的最后5个填充来解决的。

编辑这实际上不仅仅是省略了结尾的5个字符。由于我发现乱码或填充的数量取决于原始JSON的长度,因此通过检测JSON字符串的末尾来修剪字符串更有意义。

我提供我的(更新)工作代码作为参考。我希望这篇文章能帮助那些也有这个问题的人!祝你的项目好运!

代码语言:javascript
复制
#include "AES.h"
#include "Base64.h"

AES aes;

// Our AES key. Same in NodeJS but in hex bytes
byte key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C };
// The unitialized Initialization vector (16-bit)
byte iv[N_BLOCK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

// NodeMCU side raw message
String msg = "{\"x\":10, \"y\":20, \"z\":30 \"lamp_stat\":\"ON  This is a sentence. Testing testing testing\"}";

uint8_t generate_random_unit8()
{
  uint8_t really_random = *(volatile uint8_t *)0x3FF20E44;
  return really_random;
}

// Generate a random initialization vector
void generate_iv(byte *vector)
{
  for (int i = 0; i < N_BLOCK; i++)
  {
    vector[i] = (byte)generate_random_unit8();
  }
}

void encrypt()
{
  char b64data[200];
  byte cipher[1000];
  byte iv[N_BLOCK];

  generate_iv(iv);

  base64_encode(b64data, (char *)iv, N_BLOCK);
  String IV_base64 = String(b64data);
  Serial.println(" IV b64: " + IV_base64);

  int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length());

  Serial.println(" The lenght is:  " + String(b64len));

  // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding
  aes.do_aes_encrypt((byte *)b64data, b64len, cipher, key, 128, iv);

  Serial.println("Cipher size: " + String(aes.get_size()));

  base64_encode(b64data, (char *)cipher, aes.get_size());
  Serial.println("Encrypted data in base64: " + String(b64data));

  //decrypt(b64data, IV_base64, aes.get_size());
}

void decrypt(String b64data, String IV_base64, int lsize)
{
  char data_decoded[300];
  char iv_decoded[300];
  byte out[300];
  char temp[300];
  b64data.toCharArray(temp, 300);
  base64_decode(data_decoded, temp, b64data.length());
  IV_base64.toCharArray(temp, 300);
  base64_decode(iv_decoded, temp, IV_base64.length());
  aes.do_aes_decrypt((byte *)data_decoded, lsize, out, key, 128, (byte *)iv_decoded);
  char message[msg.length()];
  base64_decode(message, (char *)out, aes.get_size());
  for (int i = 0; i < aes.get_size(); i++)
  {
    char curChar = (char)message[i];
    if (curChar != '}')
      temp[i] = curChar;
    else
    {
      temp[i] = curChar;
      temp[i+1] = '\0';
      break;
    }
  }
  String result = String((char *)temp);
  Serial.println(result);
}

void setup_aes()
{
  aes.set_key(key, sizeof(key)); // Get the globally defined key
}

void setup()
{
  Serial.begin(115200);

}

void loop()
{
  encrypt();
  decrypt("ipYk12VCYyD+aJ7KL7lO8L5zOq71XvsLzp650gKBFgQor7GHs98QpQSjQOZdhCwggq2Ehf4nVNwTeK3VjtqMVJRGBw9YViARXCTOGqctjFc=", "+eNzSlRRPi0YZhrp5ctpnA==", 83);
  delay(8000);
}
票数 1
EN

Stack Overflow用户

发布于 2017-02-04 19:01:27

我终于找到问题所在了。

base64_decode(message, (char *)out, b64data.length());

应该是

base64_decode(message, (char *)out, 75); -编码数据的长度

至少PoC可以工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41925515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档