我正在使用esp32(Arduino平台而不是esp-idf(和"HTTPClient.h"
库将带有参数的get请求发送到我的PHP服务器。
我想加密参数值并在我的 PHP 代码中解密它们,反之亦然(我的服务器将 JSON 数据发回我的 esp32(。
我尝试将XXTEA协议与这些PHP和esp32库一起使用。
但是加密的字符串在 PHP 上无法正确解密。
例:
当我使用密钥加密esp32
上的"HELLO WORLD"
时"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
之间进行加密的字符串通信?
提前谢谢。
此问题可能是由于输入的数据类型不同,因为当前的 XXTEA 实现似乎没有执行任何类型或范围检查。
或者这可能是由于所涉及的两台计算机的字节序行为不同,因为二进制通常存储为由字节构造的单词数组。
或者可能是由于缺乏正确加密特定字符串和密钥的官方或标准参考示例。在没有参考示例(使用二进制加密结果的十六进制或 base64 转换(的情况下,无法判断加密实现是否正确,即使其结果使用相应的解密实现正确解密也是如此。
添加:
我想我在 XXTEA 的已发布代码中发现了一个兼容性问题。可能值得在这里花一些篇幅来讨论它。
具体来说,问题在于不同的实现为加密相同的明文和密钥创建了不同的结果。
讨论:
此问题是由于将明文的长度添加为长整型数组的最后一个元素而导致的。虽然这解决了长度不是 4 的倍数的明文问题,但它生成的加密值与 JavaScript 实现生成的加密值不同。
如果在 long2str 和 str2long 函数的开头插入 "$w=false;",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"。换句话说,生成的字符串填充了从未见过的 NULL,即使 JavaScript(如 PHP(可以在字符串中包含 NULL,因为它单独存储长度。
我对哪种方法最好没有意见,但应该为所有实现选择一种方法。
加密结果应该有一个标准的原因是(无论二进制文件是转换为十六进制还是 base64 以实现安全传输(是人们可能想要使用 PHP 进行编码,但使用 JavaScript 进行解码,这取决于在两个位置使用哪种语言是自然的。毕竟,加密最常用于两个位置之间的通信,目标位置使用的语言甚至可能不知道。
为什么不使用wificlientsecure库?在 esp32 上效果很好。