输入具有不同的数据类型可能会导致此问题,因为当前没有任何类型或范围检查的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”。换句话说,生成的字符串用从未见过的NUL填充,即使JavaScript(如PHP)可以在字符串中包含NUL,因为它分别存储长度。
我对哪种方法最好是没有意见,但应该为所有实现选择一种方法。
应该有加密结果标准的原因(无论二进制文件是转换为十六进制还是转换为base64以便安全传输),人们可能希望使用PHP进行编码,而使用JavaScript进行解码,具体取决于在两个地方使用哪种语言是很自然的。毕竟,加密最常用于在两个位置之间进行通信,并且目标位置使用的语言甚至可能都不知道。