1

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

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

当我将我的 oauth 提供者和客户端切换为使用 PLAINTEXT 签名方法(我知道这对安全性不利)时,它适用于所有平台。

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

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

什么可能导致使用 HmacSHA1 签名算法的 Base64.encode() 方法在两个系统上使用相同的参数和密码产生不同的结果?

提前致谢!--TK

4

1 回答 1

1

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

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

我经常看到这样的错误(String.getBytes("test"))——它是现有的最常见的 Java 反模式之一。最糟糕的是,只有在特定情况下才会导致问题的错误,所以人们并没有被咬到足以修复这些问题。

另一个潜在问题是 URL 编码——由于编码/解码中的细微错误,某些字符(空格、%、+)的处理可能因实现而异。因此,您可以查看您传递的内容是否包含“特殊”字符;尝试查看消除它们(用于测试)是否会产生影响,而触发差异的因素为零。

于 2011-06-17T17:39:10.713 回答