Функция Clojure SHA256 HMAC не дает ожидаемых результатов
У меня есть следующий код Clojure:
(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)))
Когда я использую sign
функция в REPL, странные глифы выводятся:
(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
Это, несомненно, проблема кодирования строк, но я не особо разбираюсь в кодировании. Кто-нибудь может помочь?
1 ответ
Решение
Чтобы поместить вывод в формат, который можно сравнить с примерами, не вызывайте 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)))