java
  • javascript
  • hmacsha1
  • 2014-08-31 95 views 1 likes 
    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

    +0

    這兩個散列字符串是否相等?服務器上的request.uri與客戶端上的requestUrl相同嗎? JSON格式('asJson')怎麼樣?你知道你必須構造相同的結構以獲得相同的簽名結果,對嗎? – 2014-08-31 12:34:54

    +0

    另請注意,兩個簽名具有相同的長度......您只是將其中一個打印爲HEX字符串,而另一個則將其打印爲BASE64字符串。 – 2014-08-31 12:36:31

    +0

    啊...好的。只需將客戶端生成的簽名轉換爲base64即可使用。我會更新我的帖子。非常感謝你。 – j3d 2014-08-31 12:50:21

    回答

    0

    正如Pavel所述,問題是我在客戶端使用了十六進制表示,而在服務器上使用了BASE64表示。爲了解決這個問題,我只是像這樣修改客戶端:

    <script src='lib/hmac-sha1.js' type='text/javascript'></script> 
    <script src='lib/enc-base64-min.js' type='text/javascript'></script> 
    
    ... 
    
    var token = ... 
    var signature = CryptoJS.HmacSHA1(token + httpMethod + requestUrl + requestBody), apiKey).toString(CryptoJS.enc.Base64); 
    headers["Authorization"] = "MyAuth " + token + ":" + signature; 
    

    ;

    非常感謝Pavel。

    相關問題