如何使用Crypto ++库创建HMAC 256?

时间:2016-09-27 09:27:54

标签: c++ cryptography hmac crypto++

我有一个字符串,我需要使用C ++和Crypto ++在HMAC 256中进行编码。库wiki中的代码:

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

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

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

// Pretty print key
encoded.clear();
StringSource ss1(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 ss2(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 ss3(mac, true,
    new HexEncoder(
        new StringSink(encoded)
    ) // HexEncoder
); // StringSource

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

这个例子提供了作品,但似乎做了很多事情。我所要做的就是:

  1. 取一个字符串:“GreatWallOfChina”
  2. key:m2hspk1ZxsjlsDU6JhMvD3TQQhm + zOwab3slKEILoSSnfk3b2 + NUyeJiCrRAJ / D3V5y + QDZaIqRx9q9siMopaA ==
  3. 将密钥转换为base64:bTJoc3BrMVp4c2psc0RVNkpoTXZEM1RRUWhtK3pPd2FiM3NsS0VJTG9TU25mazNiMitOVXllSmlDclJBSi9EM1Y1eStRRFphSXFSeDlxOXNpTW9wYUE9PQ ==
  4. 使用该base64密钥创建hmac256。
  5. 所以,我的问题是,上面的示例代码中的所有步骤都是必要的吗? (字节块声明,十六进制编码等)

    如果这是一个非常无趣的问题,请道歉。

3 个答案:

答案 0 :(得分:2)

不,您的步骤当然不是必需的,例如base 64编码已经基本的64位编码值。

Crypto ++主要基于带有接收器和源的流式传输。这就是图书馆的设置方式,但对于小型计算,它会有些冗长。

请注意,大多数示例代码只是密钥生成并打印出明文,密钥和身份验证标记(MAC值)以及一些异常处理。所需的代码基本上位于try / catch块内。

答案 1 :(得分:1)

  

所以,我的问题是,上面的示例代码中的所有步骤都是必要的吗?

嗯,问题的答案是,大多数情况是肯定的。但请记住,代码是作为维基的一个例子编写的。

您可能需要也可能不需要此功能。但似乎你会输入一个键和一个字符串。

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

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

如果你不是用ASCII打印它,你可能不需要这个:

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

删除上面的代码之后,剩下的就在下面,这对我来说似乎并不过分:

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

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

答案 2 :(得分:0)

我发现某人(woodja)做了同样的事情,但是对于aws:

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include "cryptopp/cryptlib.h"
using CryptoPP::Exception;

#include "cryptopp/hmac.h"
using CryptoPP::HMAC;

#include "cryptopp/sha.h"
using CryptoPP::SHA256;

#include "cryptopp/base64.h"
using CryptoPP::Base64Encoder;

#include "cryptopp/filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::HashFilter;

string sign(string key, string plain)
{
        string mac, encoded;
        try
        {
                HMAC< SHA256 > hmac((byte*)key.c_str(), key.length());

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

        encoded.clear();
        StringSource(mac, true,
                new Base64Encoder(
                        new StringSink(encoded)
                ) // Base64Encoder
        ); // StringSource
        std::cout << "encode: " << encoded << endl;
        return encoded;
}

int main()
{
        string mykey = "m2hspk1ZxsjlsDU6JhMvD3TQQhm+zOwab3slKEILoSSnfk3b2+NUyeJiCrRAJ/D3V5y+QDZaIqRx9q9siMopaA==";
        string msg = "GreatWallOfChina";
        std::cout << "key: " << mykey << std::endl;
        std::cout << "msg: " << msg << std::endl;
        sign(mykey,msg);
        return 0;
}

Github answer