[英]How use custom key in HMAC-SHA1 Crypto++ realisation
I want to implement OAuth 1.0
protocol in my C++ project. 我想在我的C ++项目中实现
OAuth 1.0
协议。 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. 为了创建OAuth签名,我需要实现
HMAC-SHA1
算法,其中key
和text
将是根据OAuth规范创建的一些字符串。
I want to use Crypto++ library for implementing HMAC-SHA1. 我想使用Crypto ++库来实现HMAC-SHA1。 I found this HMAC-SHA1 example on wiki of project:
我在项目的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;
But I can't understand how instead of random generated string use my created key
. 但我无法理解如何使用我创建的
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).
因为我将拥有不同长度的键(48和96符号)。
It appears there are a few things you need to get familiar with. 看来你需要熟悉一些东西。 (Sorry I can't help because I've never had to do it).
(对不起,我无法帮助,因为我从来没有这样做过)。
First is the Security Architecture. 首先是安全架构。 You can find some reading at Beginner's Guide to OAuth – Part III : Security Architecture .
您可以在初学者OAuth指南 - 第三部分:安全架构中找到一些内容。
Second is the HMAC-SHA1 signature and format. 其次是HMAC-SHA1签名和格式。 You can find the overview at OAuth Core HMAC-SHA1 .
您可以在OAuth Core HMAC-SHA1上找到概述。
Third, you need to understand OAuth's encoding and presentation format. 第三,您需要了解OAuth的编码和表示格式。 You can find some reading at OAuth Core Parameter Encoding .
您可以在OAuth核心参数编码中找到一些阅读材料。
To answer some of your questions: 回答你的一些问题:
You will need to parse and decode the parameters to get the key, signed data, and signature. 您需要解析和解码参数以获取密钥,签名数据和签名。 So you will need to parse and decode three values:
oauth_key
, oauth_data
and oauth_signature
. 因此,您需要解析和解码三个值:
oauth_key
, oauth_data
和oauth_signature
。
Then, you will set up your Crypto++ HMAC key
as follows. 然后,您将按如下方式设置Crypto ++ HMAC
key
。
SecByteBlock key(SHA1::BLOCKSIZE);
memcpy(key.data(), key.size(), oauth_key);
After that, you would verify with the following: 之后,您将验证以下内容:
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;
}
Another thing Crypto++ might be able to help with is Base64 decoding. Crypto ++可能能够帮助的另一件事是Base64解码。 Below is from the HexDecoder wiki page , but it applies to
Base64Decoder
because the encoders and decoders use the same interface. 下面是从HexDecoder wiki页面 ,但它适用于
Base64Decoder
因为编码器和解码器使用相同的接口。
string encoded = ...;
string decoded;
StringSource ss(encoded,
new HexDecoder(
new StringSink(decoded)
) // HexDecoder
); // StringSource
So your code would be: 所以你的代码是:
string encoded = ...;
string decoded;
StringSource ss(encoded,
new Base64Decoder(
new StringSink(decoded)
) // Base64Decoder
); // StringSource
The above uses Crypto++'s pipline interface, where data flows from a source to a sink. 以上使用Crypto ++的pipline接口,其中数据从源流到接收器。 You can also do it in a more "C" like manner using
Put
and Get
on the Base64Decoder
object: 您也可以使用
Base64Decoder
对象上的Put
和Get
以更“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());
}
I was tasked with a very similar task. 我的任务非常相似。 Do two-legged OAuth 1.0a in C++.
在C ++中做两条腿的OAuth 1.0a。 Two-legged because there is no user involved in the process, only the client and the server.
两条腿因为没有用户参与该过程,只有客户端和服务器。 As described in: http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html
如下所述: http : //oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html
The complete proof of concept including parsing and decoding the parameters can be found at: https://gist.github.com/duedal/a197fc9f6dc1ad59f08c 完整的概念证明包括解析和解码参数可以在以下网址找到: https : //gist.github.com/duedal/a197fc9f6dc1ad59f08c
Should be easy to build on this to complete it. 应该很容易在此基础上完成它。 Mainly need to validate the timestamp+nonce, and of course tie into your project.
主要需要验证时间戳+ nonce,当然还要绑定到你的项目中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.