2013-03-15 59 views
3

我有以下的Clojure代碼:Clojure的SHA256 HMAC功能沒有產生預期的效果

(ns myproject.hmac-sha256 
    (:import (javax.crypto Mac) 
      (javax.crypto.spec SecretKeySpec))) 

(defn secretKeyInst [key mac] 
    (SecretKeySpec. (.getBytes key) (.getAlgorithm mac))) 

(defn toString [bytes] 
    "Convert bytes to a String" 
    (String. bytes "UTF-8")) 

(defn sign [key string] 
    "Returns the signature of a string with a given 
    key, using a SHA-256 HMAC." 
    (let [mac (Mac/getInstance "HMACSHA256") 
      secretKey (secretKeyInst key mac)] 
      (-> (doto mac 
       (.init secretKey) 
       (.update (.getBytes "UTF-8"))) 
       .doFinal 
       toString))) 

當我在REPL使用sign功能,奇怪的符號,是輸出:

(sign "key" "The quick brown fox jumps over the lazy dog") 
"*��`��n�S�F�|�؏�o�r���" 

,而我是預計f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8根據https://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29

這無疑是一個字符串編碼問題,但我對編碼並不十分了解。誰能幫忙?

回答

5

要使輸出成可與所述實施例不調用上文所定義的的toString進行比較的格式,而不是治療.doFinal的結果作爲一個字節數組,以十六進制打印。上面的例子是簽名字符串「UTF-8」,而不是輸入字符串:

(defn sign [key string] 
    "Returns the signature of a string with a given 
    key, using a SHA-256 HMAC." 
    (let [mac (Mac/getInstance "HMACSHA256") 
     secretKey (secretKeyInst key mac)] 
    (-> (doto mac 
      (.init secretKey) 
      (.update (.getBytes string))) 
     .doFinal))) 

myproject.hmac-sha256> (apply str (map #(format "%x" %) (sign "key" "The quick brown fox jumps over the lazy dog"))) 
"f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" 

然後你可以寫的toString功能是這樣的:

(defn toHexString [bytes] 
    "Convert bytes to a String" 
    (apply str (map #(format "%x" %) bytes))) 
+0

檢查由.getBytes產生的實際字節,並使用哪個填充。 – 2013-03-16 00:17:32