Java-эквивалент Fantom HMAC с использованием SHA1 - PullRequest
3 голосов
/ 14 июля 2011

У меня проблемы с выполнением следующих действий на Java. Ниже приведен код Fantom из документации на инструмент, который я использую.

// compute salted hmac
hmac := Buf().print("$username:$userSalt").hmac("SHA-1", password.toBuf).toBase64

// now compute login digest using nonce
digest := "${hmac}:${nonce}".toBuf.toDigest("SHA-1").toBase64

// our example variables
username: "jack"
password: "pass"
userSalt: "6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU="
nonce:    "3da210bdb1163d0d41d3c516314cbd6e"
hmac:     "IjJOApgvDoVDk9J6NiyWdktItl0="
digest:   "t/nzXF3n0zzH4JhXtihT8FC1N3s="

Я искал различные примеры в Google, но ни один из них не дал результатов, по которым должны быть возвращены претензии по документации.

Может ли кто-нибудь со знанием Fantom проверить, верен ли пример в документации?

Что касается Java, вот моя последняя попытка

    public static String hmacSha1(String value, String key) {
    try {
        // Get an hmac_sha1 key from the raw key bytes
        byte[] keyBytes = key.getBytes("UTF-8");           
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");

        // Get an hmac_sha1 Mac instance and initialize with the signing key
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);

        // Compute the hmac on input data bytes
        byte[] rawHmac = mac.doFinal(value.getBytes("UTF-8"));

        // Convert raw bytes to Hex
        byte[] hexBytes = new Hex().encode(rawHmac);

        //  Covert array of Hex bytes to a String
        return new String(hexBytes, "UTF-8");
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Однако, когда я вызываю метод со следующими параметрами

jack:6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU=
pass

Я получаю

22324e02982f0e854393d27a362c96764b48b65d

Ответы [ 2 ]

2 голосов
/ 14 июля 2011

Не знаю, откуда появились документы, но они могут быть устаревшими или неправильными.Я бы на самом деле запустил код Fantom, чтобы использовать его в качестве ссылки, чтобы убедиться, что вы тестируете нужные вещи;)

Вы можете взглянуть на исходный код Java для sys :: Buf.hmac: MemBuf.java

Я бы также рекомендовал выделить 3 преобразования.Убедитесь, что ваш необработанный байтовый массив совпадает как в Fantom, так и в Java, затем проверьте совпадения дайджеста и, наконец, кодировку Base64.Намного проще проверить каждый этап в вашем коде.

1 голос
/ 15 июля 2011

Оказывается, это было только мое отсутствие знаний, и с достаточным количеством проб и ошибок я смог понять это, выполнив следующее:

//username: "jack"
//password: "pass"
//userSalt: "6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU="
//nonce:    "3da210bdb1163d0d41d3c516314cbd6e"
//hmac:     "IjJOApgvDoVDk9J6NiyWdktItl0="
//digest:   "t/nzXF3n0zzH4JhXtihT8FC1N3s="

...
// initialize a Mac instance using a signing key from the password
SecretKeySpec signingKey = new SecretKeySpec(password.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);

// compute salted hmac
byte[] hmacByteArray = mac.doFinal((username + ':' + userSalt).getBytes());
String hmacString = new String(Base64.encodeBase64(hmacByteArray));
// hmacString == hmac

// now compute login digest using nonce
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update((hmacString + ':' + nonce).getBytes());
byte[] digestByteArray = md.digest();
String digestString = new String(Base64.encodeBase64(digestByteArray));
// digestString == digest

Используется org.apache.commons.codec.binary.Base64 для кодирования байтовых массивов.

...