esp32和php XXTEA字符串加密

时间:2018-09-13 11:22:08

标签: php arduino esp32 xxtea

我将esp32(不是esp-idf的Arduino平台)与"HTTPClient.h"库一起使用,将带有参数的获取请求发送到我的PHP服务器。

我想加密参数值并在我的PHP代码中解密它们,反之亦然(我的服务器将JSON数据发送回我的esp32)。

我尝试对这些PHPesp32这些库使用XXTEA协议。

但是加密的字符串无法在PHP上正确解密。

示例:

当我使用密钥"HELLO WORLD"esp32上的"ENCRYPTION KEY"进行加密时,我会得到:

  

35bd3126715874f741518f4d

当我在PHP上解密时,它返回空白。

此外,当我在PHP服务器上对其进行加密时,我得到了:

  

T1YNYC4P4R2Y5eCxUqtjuw==

我的esp32草图如下:

#include <xxtea-iot-crypt.h>

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

void loop() {
  String plaintext = "HELLO WORLD";

  // Set the Password
  xxtea.setKey("ENCRYPTION KEY");

  // Perform Encryption on the Data
  Serial.print(F(" Encrypted Data: "));
  String result = xxtea.encrypt(plaintext);

  Serial.println(result);

  // Perform Decryption
  Serial.print(F(" Decrypted Data: "));
  Serial.println(xxtea.decrypt(result));
  delay(2000);

}

我的PHP代码如下:

require_once('xxtea.php');
$str = "HELLO WORLD"
$key = "ENCRYPTION KEY";
$encrypt_data = xxtea_encrypt($str, $key);
error_log($encrypt_data);

是否可以在PHP和esp32之间进行加密的字符串通信?

谢谢。

2 个答案:

答案 0 :(得分:1)

此问题可能是由于输入的数据类型不同而引起的,因为当前的XXTEA实现似乎没有进行任何类型或范围检查。

或者可能是由于所涉及的两台计算机的字节序行为不同,因为二进制通常存储为由字节构成的单词数组。

或者可能是由于缺少用于正确加密特定字符串和密钥的官方或标准参考示例。在没有参考示例的情况下(使用二进制加密结果的十六进制或base64转换),即使其结果使用相应的解密实现正确解密,也无法判断加密实现是否正确。

已添加:

我认为我在XXTEA的已发布代码中发现了一个兼容性问题。在这里可能需要花一些空间来讨论它。

具体地说,问题在于,不同的实现会为加密相同的明文和密钥产生不同的结果。

讨论:

此问题是由于增加了明文的长度作为long数组的最后一个元素。虽然这解决了长度不是4的倍数的纯文本的问题,但它产生的加密值与JavaScript实现产生的值不同。

如果您插入“ $ w = false;”在long2str和str2long函数的开头,PHP实现的加密值变得与JavaScript实现相同,但是解密后的值在末尾带有垃圾。

以下是此更改的一些测试用例结果:

PHP:

text:    >This is an example. !@#$%^&*(){}[]:;<
Base64:  PlRoaXMgaXMgYW4gZXhhbXBsZS4gIUAjJCVeJiooKXt9W106Ozw=
key:     8GmZWww5T97jb39W
encrypt: sIubYrII6jVXvMikX1oQivyOXC07bV1CoC81ZswcCV4tkg5CnrTtqQ==
decrypt: >This is an example. !@#$%^&*(){}[]:;<��

注意:“解密”行的末尾有两个UTF-8问号字符。

JavaScript:

text:    >This is an example. !@#$%^&*(){}[]:;<
Base64:  PlRoaXMgaXMgYW4gZXhhbXBsZS4gIUAjJCVeJiooKXt9W106Ozw=
key:     8GmZWww5T97jb39W
encrypt: sIubYrII6jVXvMikX1oQivyOXC07bV1CoC81ZswcCV4tkg5CnrTtqQ==
decrypt: >This is an example. !@#$%^&*(){}[]:;<

即使没有保存纯文本的长度,JavaScript实现中也没有垃圾的原因在其中的注释中给出:“注意,从字符串末尾运行会产生空值,因为按位运算符会将NaN视为0” 。换句话说,即使像PHP这样的JavaScript可以将NUL包含在字符串中,因为生成的字符串会分别存储长度,因此,这些字符串将被填充从未被看到的NUL。

对于哪种方法最好,我没有意见,但是所有实现都应该选择一种方法。

应该有一个标准的加密结果(无论二进制文件是安全转换为十六进制还是base64),是因为人们可能想使用PHP进行编码,而使用JavaScript进行解码,这取决于在两个位置自然使用哪种语言。毕竟,加密最常用于两个位置之间的通信,并且甚至可能不知道目标位置使用的语言。

答案 1 :(得分:0)

为什么不使用wificlientsecure库?在esp32上效果很好。