加密 IV - C 和 Python 等效

Encryption IV - C and Python equivalent

我在为我的消息加密初始化等价物 "initialization vectors" 时遇到问题。 我有一个 ESP32(微控制器)通过 JSON 将数据发送到 Django 服务器。在 ESP32 上我使用的是 Arduino IDE,所以 ESP32 上的代码是用 C/C++ 编写的。 Django 当然是使用 Python.

如果我在两边都像这样初始化 IV,那么我的加密到目前为止是有效的:

ESP32:

unsigned char iv[16] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};

姜戈:

iv = b'0000000000000000'

ESP32的库有一个加密函数,需要一个unsigned char数组。我必须注意该数组不是以 null 结尾的(末尾为“\0”),否则我会得到不同的结果。 以上就是背景资料。你需要。现在针对我的具体问题:

我想在我的加密中使用计数器模式。我想复制一个整数计数器到 IV 两边的最后 4 个字节:

在 ESP32 上我这样做:

int msg_counter = 15 //15 just as an example
memcpy(iv+12, &msg_counter, sizeof(msg_counter));

在 Django 上我这样做:

counter = (int) 15;
iv = counter.to_bytes(16, byteorder = 'big')

如果我打印出变量 "iv" 我在 Django 上得到这个:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f'

解密失败。我没有从服务器上的 ESP32 收到原始消息。

如果我不像上面那样初始化 IV,我总是会得到不同的结果。

我在 Django 上为 encryption/decryption 使用 PyCryptoDome。 我将 IV 传递给这行代码: obj = AES.new(enckey, AES.MODE_CFB, iv, segment_size = 128) IV 必须以类似 b'0000000000000000' 的格式传递。所以我在服务器端没有任何其他选择。

如果我在 ESP32 上这样做:

memset(iv,0,16);

b'0000000000000000'

在 Django 上我得到了不同的结果。不知道怎么办。

有什么想法吗?

根据其 technical manual, the ESP32 stores data in little-endian 格式的第 1.3.1 节。这意味着 IV 创建者:

int msg_counter = 15;
memcpy(iv+12, &msg_counter, sizeof(msg_counter));

看起来像:

0 0 0 0 0 0 0 0 0 0 0 0 0x0F 0 0 0

要在 Python 中实现相同的目标,您需要执行以下操作:

msg_counter = 15
iv = iv[:12] + msg_counter.to_bytes(4, byteorder="little")

我不断尝试,自己发现了。

在 ESP32 上你必须做的:

int msg_counter = 15;
unsigned char iv[16];
unsigned char bytes[4];
bytes[0] = (msg_counter >> 24) & 0xFF;
bytes[1] = (msg_counter >> 16) & 0xFF;
bytes[2] = (msg_counter >> 8) & 0xFF;
bytes[3] = msg_counter & 0xFF;
memcpy(iv+12, bytes, sizeof(bytes));

在 Django 上:

counter = 15;
iv = counter.to_bytes(16, byteorder = 'big')