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