Как использовать пользовательский ключ в реализации Crypto ++ HMAC-SHA1

Я хочу реализовать OAuth 1.0 протокол в моем C ++ проекте. Для того чтобы создать подпись OAuth мне нужно реализовать HMAC-SHA1 алгоритм где key а также text будет некоторая строка, созданная в соответствии со спецификацией OAuth.

Я хочу использовать библиотеку Crypto ++ для реализации HMAC-SHA1. Я нашел этот пример HMAC-SHA1 на вики проекта:

AutoSeededRandomPool prng;

SecByteBlock key(16);
prng.GenerateBlock(key, key.size());

string plain = "HMAC Test";
string mac, encoded;

/*********************************\
\*********************************/

// Pretty print key
encoded.clear();
StringSource(key, key.size(), true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource

cout << "key: " << encoded << endl;
cout << "plain text: " << plain << endl;

/*********************************\
\*********************************/

try
{
HMAC< SHA256 > hmac(key, key.size());

StringSource(plain, true,
new HashFilter(hmac,
new StringSink(mac)
) // HashFilter
); // StringSource
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
exit(1);
}

/*********************************\
\*********************************/

// Pretty print
encoded.clear();
StringSource(mac, true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource

cout << "hmac: " << encoded << endl;

Но я не могу понять, как вместо случайно сгенерированной строки использовать мою созданную key, Я пытался просто создать:

string key=...; //string generated by OAuth specification;

Но тогда появляются ошибки компиляции. Однако, когда я пишу:

string plain=...; //string generated by OAuth specification;

Тогда нет ошибок.

И какую длину ключа мне нужно указать? Потому что у меня будут ключи разной длины (с 48 и, возможно, 96 символами).

4

Решение

Похоже, есть несколько вещей, с которыми вам нужно ознакомиться. (Извините, я не могу помочь, потому что мне никогда не приходилось это делать).

Во-первых, это архитектура безопасности. Вы можете найти некоторые чтения на Руководство для начинающих по OAuth — часть III: архитектура безопасности.

Во-вторых, подпись и формат HMAC-SHA1. Вы можете найти обзор на OAuth Core HMAC-SHA1.

В-третьих, вы должны понимать формат кодирования и представления OAuth. Вы можете найти некоторые чтения на Кодирование основного параметра OAuth.


Чтобы ответить на некоторые ваши вопросы:

Вам нужно будет проанализировать и декодировать параметры, чтобы получить ключ, подписанные данные и подпись. Так что вам нужно будет проанализировать и декодировать три значения: oauth_key, oauth_data а также oauth_signature,

Затем вы настроите свой Crypto ++ HMAC key следующее.

SecByteBlock key(SHA1::BLOCKSIZE);
memcpy(key.data(), key.size(), oauth_key);

После этого вы должны проверить следующее:

byte oauth_key[] = ...; // Your parsed and decoded key
string oauth_data = ...; // Your parsed and decoded data
string oauth_signature = ...; // // Your parsed and decoded signature

try
{
SecByteBlock key(SHA1::BLOCKSIZE);
memcpy(key.data(), key.size(), oauth_key);

HMAC< SHA1 > hmac(key, key.size());
const int flags = HashVerificationFilter::THROW_EXCEPTION | HashVerificationFilter::HASH_AT_END;

StringSource ss(oauth_data + oauth_signature + mac, true,
new HashVerificationFilter(hmac, NULL, flags)
); // StringSource

cout << "Verified message" << endl;
}
catch(const CryptoPP::Exception& e)
{
// Handle failure
cerr << e.what() << endl;
}

Crypto ++ может помочь с декодированием Base64. Ниже из Вики-страница HexDecoder, но это относится к Base64Decoder потому что кодеры и декодеры используют один и тот же интерфейс.

string encoded = ...;
string decoded;

StringSource ss(encoded,
new HexDecoder(
new StringSink(decoded)
) // HexDecoder
); // StringSource

Итак, ваш код будет:

string encoded = ...;
string decoded;

StringSource ss(encoded,
new Base64Decoder(
new StringSink(decoded)
) // Base64Decoder
); // StringSource

Выше используется интерфейс pipline Crypto ++, где данные передаются из источника в приемник. Вы также можете сделать это в стиле «C», используя Put а также Get на Base64Decoder объект:

string encoded = ...;
string decoded;

Base64Decoder decoder;

decoder.Put( (byte*)encoded.data(), encoded.size() );
decoder.MessageEnd();

word64 size = decoder.MaxRetrievable();
if(size && size <= SIZE_MAX)
{
decoded.resize(size);
decoder.Get((byte*)decoded.data(), decoded.size());
}
4

Другие решения

Передо мной стояла очень похожая задача. Сделайте двуногую OAuth 1.0a в C ++. Двуногие, потому что в этом процессе нет пользователя, только клиент и сервер. Как описано в: http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html

Полное подтверждение концепции, включая анализ и декодирование параметров, можно найти по адресу: https://gist.github.com/duedal/a197fc9f6dc1ad59f08c

Должно быть легко основываться на этом, чтобы закончить это. В основном нужно проверить временную метку + nonce, и, конечно, привязать к вашему проекту.

0

По вопросам рекламы [email protected]