1
签署HTTP请求我的REST API的授权模式包括HTTP标头是这样的:与HMAC SHA1
"Authorization: MyAuth: JWT_VALUE:207112ade53c795df43ce38e5251b41ded1791aa"
JWT_VALUE
是一个标准的JSON网络令牌还包含加密的API密钥作为自定义要求。冒号后的第二部分是由客户端这样生成的签名:
<script src='lib/hmac-sha1.js' type='text/javascript'></script>
...
var token = ...
var signature = CryptoJS.HmacSHA1(token + httpMethod + requestUrl + requestBody), apiKey);
headers["Authorization"] = "MyAuth " + token + ":" + signature;
的问题是,我无法在服务器上生成相同的签名;这里是我的Scala代码:
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Base64
...
val data = token + request.method + request.uri + request.body.asInstanceOf[AnyContent].asJson.getOrElse("")
val secret = ... // extract api key from token and decrypt it with app secret key
val singed = sign(data, secret)
if (signed != request.signature) {
// error
...
}
...
def sign(data: String, secret: String): String = {
val mac = Mac.getInstance("HmacSHA1")
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA1"))
Base64.encodeBase64String(mac.doFinal(data))
}
下面是我在我的调试会话得到一个例子:
Incoming request signed by the server =========> um/TemuwSzboWD1D4kLRnFD6Sxk=
Signature generated by the client =============> 1c0567113a6bcc9f3715b83182d62e11aff52cec
正如你可以看到由服务器javax.crypto.Mac
产生的签名比一个短由客户端生成CryptoJs
。
这两个散列字符串是否相等?服务器上的request.uri与客户端上的requestUrl相同吗? JSON格式('asJson')怎么样?你知道你必须构造相同的结构以获得相同的签名结果,对吗? – 2014-08-31 12:34:54
另请注意,两个签名具有相同的长度......您只是将其中一个打印为HEX字符串,而另一个则将其打印为BASE64字符串。 – 2014-08-31 12:36:31
啊...好的。只需将客户端生成的签名转换为base64即可使用。我会更新我的帖子。非常感谢你。 – j3d 2014-08-31 12:50:21