简体   繁体   English

如何在HMAC-SHA1 Crypto ++实现中使用自定义密钥

[英]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算法,其中keytext将是根据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_keyoauth_dataoauth_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对象上的PutGet以更“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM