4

I want to implement OAuth 1.0 protocol in my C++ project. In order to create OAuth signature I need to implement HMAC-SHA1 algorithm where key and text will be some string created according to OAuth specification.

I want to use Crypto++ library for implementing HMAC-SHA1. I found this HMAC-SHA1 example on wiki of project:

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;

But I can't understand how instead of random generated string use my created key. I tried just create:

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

But then appear compiling errors. However when I write:

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

Then there is no errors.

And what key length I need to specify? Because I will have keys of different lengths (with 48 and maybe 96 symbols).

4

2 回答 2

4

看来您需要熟悉一些事情。(对不起,我无能为力,因为我从来没有这样做过)。

首先是安全架构。您可以在OAuth 初学者指南 – 第 III 部分:安全架构中找到一些阅读材料。

其次是 HMAC-SHA1 签名和格式。您可以在OAuth Core HMAC-SHA1中找到概述。

第三,您需要了解 OAuth 的编码和表示格式。您可以在OAuth Core Parameter Encoding找到一些阅读材料。


要回答您的一些问题:

您将需要解析和解码参数以获取密钥、签名数据和签名。因此,您将需要解析和解码三个值oauth_keyoauth_dataoauth_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 wiki 页面,但它适用于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

以上使用 Crypto++ 的管道接口,其中数据从源流向接收器。您也可以在对象上使用Put和以更像“C”的方式执行此操作:GetBase64Decoder

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());
}
于 2014-01-13T05:53:05.977 回答
0

我的任务非常相似。在 C++ 中执行两条腿的 OAuth 1.0a。两条腿因为没有用户参与该过程,只有客户端和服务器。如中所述:http: //oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html

包含解析和解码参数的完整概念证明可以在以下位置找到:https ://gist.github.com/duedal/a197fc9f6dc1ad59f08c

应该很容易在此基础上完成它。主要需要验证timestamp+nonce,当然要绑定到你的项目中。

于 2014-08-07T14:42:35.797 回答