HmacSHA1使用相同的秘密在不同的系统上生成不同的签名

时间:2011-06-17 16:23:25

标签: java algorithm oauth hmacsha1

我有一个使用HmacSHA1签名/验证请求的泽西oauth提供商。这适用于我的开发和客户端和测试平台服务器都是不同的物理系统。但是,当我转移到生产平台时,HmacSHA1算法(提供者端)返回的值与HmacSHA1算法(客户端)不同,使用相同的参数和&秘密,我的oauth验证失败。

JDK(1.6.x)在所有平台的提供者和客户端上都是完全相同的版本。

当我改变我的oauth提供者&客户端使用PLAINTEXT签名方法(我知道安全性不好),它适用于所有平台。

当我深入研究球衣OAuthSignature.verify()方法时,它会调用签名方法(HmacSHA1或PLAINTEXT)验证函数,该函数只使用秘密对oauth元素进行签名,并将值与传入的签名进行比较。

对于HmacSHA1,该方法调用Base64.encode()方法生成签名,但对于PLAINTEXT,不进行编码(如预期的那样)。

使用HmacSHA1签名算法的Base64.encode()方法可能会导致使用相同的params&这两个系统都有秘密吗?

提前致谢! --TK

1 个答案:

答案 0 :(得分:1)

一个有根据的猜测:如果平台编码不同(很常见;一些平台使用ISO-8859-1,其他平台使用UTF-8,Windows可能是CP-1250或其他什么,并且有问题的OAuth库有新手错误,其中未指定编码在byte []和String之间进行转换时,有些字符在不同的编码上编码不同(通常只有7位ASCII范围,字符0 - 127),最终会有不同的签名。

所以 - 你可以看到平台的默认编码是什么;并首先强制它相同。如果这解决了这个问题,我会考虑将此报告为OAuth lib(或捆绑它的框架)作者的错误,或者至少在邮件列表中询问。

我经常看到这样的错误(String.getBytes(“test”)) - 它是现存最常见的Java反模式之一。最糟糕的是,它只是在特定情况下导致问题的错误,所以人们没有被严重地修复这些问题。

另一个潜在的问题是URL编码 - 由于编码/解码中的细微错误,某些字符(空格,%,+)的处理在实现之间可能不同。因此,您可以查看您传递的内容是否具有“特殊”字符;试着看看消除它们(用于测试)是否有所不同,并且在触发差异的情况下为零。