2012-04-03 6 views
6

Я чувствую себя довольно глупо, спрашивая об этом, но, поскольку я не знаю ответа, я все равно иду вперед.HEX-представление массива байтов

Я пробовал некоторый код аутентификации и хочу знать, почему массив байтов, который я получаю из Rfc2898DeriveBytes, нужно преобразовать в HEX и снова вернуться к массиву байтов, чтобы он правильно инициализировал мой объект HMACSHA1. делаю что-то глупое, или просто не хватает что-то очевидное

Мой клиент код Javascript функция, основанная на crypto-js;.

var key256bit = Crypto.PBKDF2(passwordEntered, saltBytes, 32, { iterations: 1000 }); 
var hmacBytes = Crypto.HMAC(Crypto.SHA1, url, key256bit, { asBytes: true }); 
var base64Hash = Crypto.util.bytesToBase64(hmacBytes); 

Мой код на стороне сервера следующим образом:

Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, 
               encoding.GetBytes(salt), 1000); 
    byte[] key = rfc2898.GetBytes(32); 

    // Don't think I should need to do this. 
    // However, it wont work if I initialise HMACSHA1 
    // with the rfc2898.GetBytes(32) 
    string test = ByteArrayToString(key); 

    HMACSHA1 hmacSha1 = new HMACSHA1(encoding.GetBytes(test)); 

    byte[] computedHash = hmacSha1.ComputeHash(encoding.GetBytes(requestUri)); 
    string computedHashString = Convert.ToBase64String(computedHash); 

Мой метод ByteArrayToString, который я получил из Интернета;

private static string ByteArrayToString(byte[] ba) 
{ 
    StringBuilder hex = new StringBuilder(ba.Length * 2); 
    foreach (byte b in ba) 
     hex.AppendFormat("{0:x2}", b); 
    return hex.ToString(); 
} 

Так что я могу видеть, что я получаю 32 байт от моего вызова rfc2898.GetBytes(32). Я преобразовал это в HEX с помощью метода ByteArrayToString, чтобы подтвердить, что он соответствует тому, что я вижу в моей переменной Javascript key256bit. Теперь моя тестовая переменная представляет собой строку длиной 64, и когда я передаю ее в конструктор HMACSHA1 с использованием encoding.GetBytes (test), это байтовый массив длиной 64.

Doco on crypto-js немного отсутствует, но Я думал, что вызов Crypto.PBKDF2 с параметром 32, и он создавал ключ длиной 32 байта (или 256 бит).

Любые разъяснения очень ценятся.

+0

Пожалуйста, укажите, на каком языке (ы) вы используете, когда вы размещаете фрагменты кода. Не сразу очевидно, что вы используете JavaScript в клиенте и Java на сервере. Я имею в виду, вы могли бы использовать Dalvik или C# для всех, кого я знаю. –

+0

@OldPro: Это определенно C#, а не Java. Посмотрите на обложку «string», имена методов и т. Д. –

+0

Yup. Определенно C#. Я не добавлял теги в отношении языка, так как мой вопрос уже содержит 4! Кроме того, я как бы подозревал, что основной причиной моей проблемы является отсутствие у вас понимания того, какие преобразования происходят в коде. В ближайшие дни я проведу какое-то расследование и отчитаюсь. –

ответ

3

Я подозреваю, что это корень вопроса, в PBKDF2.js:

return options && options.asBytes ? derivedKeyBytes : 
     options && options.asString ? Binary.bytesToString(derivedKeyBytes) : 
     util.bytesToHex(derivedKeyBytes); 

Поскольку вы не предоставили варианты либо asBytes или asString, это преобразование ключа в шестнадцатеричном представлении - так же, как ваш C# код делает. Таким образом, на данный момент вы : с использованием 512-битного ключа, именно потому, что вы генерируете 2 байта «используемого ключа» из каждого байта «исходного ключа».

Я подозреваю, что если вы укажете опцию asBytes в Javascript, она просто будет работать без дополнительной шестнадцатеричной части в коде C#.

Затем снова, я никогда не видел PBKDF2 раньше, так что я мог бы быть способ покинуть базу ...

+0

Это выглядит правильно для меня. Weirdness в коде Java, чтобы наверстать ошибку в коде JavaScript. Хороший улов. –

+0

@Jon.Спасибо за ваше предложение. Я посмотрю в ближайшие дни и отчитаюсь. Я подозреваю, что вы правы, хотя, просто взглянув на код для [HMAC.js] (http://code.google.com/p/crypto-js/source/browse/branches/2.x/src/HMAC .js), он преобразует ключ в байты, если он передан как строка. Мне следовало бы с самого начала приблизиться. –

Смежные вопросы