我想在我的C ++项目中实现OAuth 1.0
协议。为了创建OAuth签名,我需要实现HMAC-SHA1
算法,key
和text
将根据OAuth规范创建一些字符串。
我想使用Crypto ++库来实现HMAC-SHA1。我在项目的wiki上找到了这个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符号)。
答案 0 :(得分:4)
看来您需要熟悉一些事项。 (对不起,我无法帮助,因为我从来没有这样做过。)
首先是安全架构。您可以在Beginner's Guide to OAuth – Part III : Security Architecture找到一些阅读材料。
其次是HMAC-SHA1签名和格式。您可以在OAuth Core HMAC-SHA1找到概述。
第三,您需要了解OAuth的编码和演示格式。您可以在OAuth Core Parameter Encoding找到一些阅读材料。
回答你的一些问题:
您需要解析和解码参数以获取密钥,签名数据和签名。因此,您需要解析和解码三个值: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 wiki page,但它适用于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 ++的pipline接口,其中数据从源流向接收器。您也可以使用Put
对象上的Get
和Base64Decoder
以更“C”的方式执行此操作:
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());
}
答案 1 :(得分: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
应该很容易在此基础上完成它。主要需要验证时间戳+ nonce,当然还要绑定到你的项目中。