2012-03-16 28 views
10

我有一個tomcat服務器運行一些Java代碼,讓用戶使用API​​密鑰進行認證。該請求使用使用SHA256創建的HMAC。我有一個我用來提出請求的Ruby客戶端,由於我是加密新手,我很難讓它生成匹配的HMAC。我試圖不讓URL安全,並且匹配。所以我真的很想知道如何讓Ruby客戶端與URL安全版本匹配(因爲我無法更改Java代碼)。它最後只有一個額外的字符。預先感謝您的幫助。如何讓Ruby生成SHA256的HMAC,以保證URL與Java匹配?

對於Ruby我使用的是1.9.3和Java,我使用的是6u31以及來自apache的commons-codec-1.6.jar庫。

代碼

紅寶石:

require "openssl" 
require "base64" 

json_str = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}" 
digest = OpenSSL::Digest::Digest.new("sha256") 
key = [ "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933" ] 
hmac = OpenSSL::HMAC.digest(digest, key.pack("H*"), json_str) 

encoded_url_safe = Base64.urlsafe_encode64(hmac) 
encoded = Base64.encode64(hmac) 

puts("Encoded (Url Safe): " + encoded_url_safe) 
puts("Encoded   : " + encoded) 

的Java:

import org.apache.commons.codec.binary.Base64; 
import org.apache.commons.codec.binary.Hex; 

import javax.crypto.spec.SecretKeySpec; 
import javax.crypto.Mac; 

public class ExampleHMAC 
{ 
    public static void main(String[] args) throws Exception 
    { 
     String key = "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933"; 
     byte[] keyBytes = Hex.decodeHex(key.toCharArray()); 

     SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256"); 
     Mac mac = Mac.getInstance("HmacSHA256"); 
     mac.init(keySpec); 

     String jsonStr = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}"; 
     byte[] hmacBytes = mac.doFinal(jsonStr.getBytes()); 

     String encodedUrlSafe = Base64.encodeBase64URLSafeString(hmacBytes); 
     String encoded = Base64.encodeBase64String(hmacBytes); 

     System.out.println("Encoded (Url Safe): " + encodedUrlSafe); 
     System.out.println("Encoded   : " + encoded); 
    } 
} 

輸出

紅寶石:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM= 
Encoded   : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM= 

的Java:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM 
Encoded   : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM= 

回答

6

Ruby沒有刪除尾隨「=」 - 它不是一個絕對的要求,你可以在RFC 4648讀它只是指出,消除他們可能在某些應用中是理想。但除此之外,它保證了Ruby的URL安全編碼將與Java完全相同。

所以你要做的唯一事情就是去掉最後的「==」,例如,你可以使用正則表達式:

encoded_url_safe_.gsub!(/=+$/, "") 
+0

這正是我需要的。對RFC 4648的引用非常有幫助和深入。我不知道結尾的'='是否可選。我添加了這個正則表達式代碼,它的工作原理。謝謝。 – mvalley 2012-03-18 05:48:36