- 比如我们有个服务是PHP提供的,要求的签名方式 hmacSha256取摘要,然后 Base64编码转化成可见字符。
- PHP那边的源码是这样的
我们放到php在线调试平台取看看执行结果:
- 然后看看Java的
执行结果如下:
- 明显Java的比php的结果短了一半
- 修改代码看看真实的签名长度
执行结果:
- 明显PHP不止256位,但是前面用的算法确实是 sha256?为啥呢?原因是PHP那边用的字符串编码方式是源文件的编码方式。Java 用的unicode码,8个字节表示一个字符,PHP字符串更具源码编码方式不同,可能占用的是16个字节表示一个字符。所以PHP的长了一倍,变成了512位。
- 怎么解决其实16字节表示一个8位能表示的字符的时候,高位都是0,如果服务提供方是PHP,那么我们只能Java这边兼容PHP的编码方式。在每个字符的扩展成16字节的字符,高位都补上0。
下面是处理代码:
- 最终结果
运行结果结果:
长度是一样的了,核对签名内容也是一样的,sha256的算法得到256位,强行填充成了,512位,实在没必要。
如果是别人给你提供的服务那么你只能按照别的的规矩来,如果你是PHP服务的提供方,我建议源文件用unicode编码,毕竟sha256算法算出来的摘要的结果本来就应该是256位。
- hmac 常见算法 HmacMD5,HmacSHA1,HmacSHA256,HmacSHA384,HmacSHA512,HmacSM3 都会出类似的问题,不是hmac的算法也可能会出类似的问题,如果捏发现长度倍增,应该考虑这种情况