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

问题描述:

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

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. 键:m2hspk1ZxsjlsDU6JhMvD3TQQhm + zOwab3slKEILoSSnfk3b2 + NUyeJiCrRAJ/D3V5y + QDZaIqRx9q9siMopaA ==
  3. 转换键为base64:bTJoc3BrMVp4c2psc0RVNkpoTXZEM1RRUWhtK3pPd2FiM3NsS0VJTG9TU25mazNiMitOVXllSmlDclJBSi9EM1Y1eStRRFphSXFSeDlxOXNpTW9wYUE9PQ ==
  4. 使用该base64密钥创建hmac256。

所以,我的问题是,上面的示例代码中的所有步骤都必须? (字节块声明,十六进制编码等)

道歉,如果这是一个非常noobish的问题。

+0

步骤2是Base64编码十六进制数据:9B 68 6C A6 4D 59 C6 C8 E5 B0 35 3A 26 13 2F 0Fc74 D0 42 19 BE CC EC 1A 6F 7B 25 28 42 0B A1 24 A7 7E 4D DB DB E3 54 C9 E2 62 0A B4 40 27 F0。步骤3 Base64编码的步骤2.这是没有意义的。 – zaph

+0

@ zaph我明白你的困惑。我应该详细阐述一下。 [链接] https://docs.gdax.com/#logon [/ link] - 寻找修复连接到gdax/coinbase。作为登录的一部分,您必须使用由消息的某些内容组成的字符串对您发送的消息进行签名。 它们提供了一个nodejs示例,它似乎将提供给base64的加密密钥转换。然后用它来生成hmac。可悲的是,这是我的逻辑来自何处。另外,他们说的全部是: “没有尾随分隔符。RawData字段应该是HMAC签名的base64编码。” – LeeO

不,您的上面的步骤当然不是必要的,例如base 64编码已经基础的64位编码值。

Crypto ++主要基于流与汇和源。这只是图书馆的设置方式,但对于小型计算而言,它会有些冗长。

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

+0

你的回答是绝对正确的。我在下面添加了我的解决方案,这只不过是从github对woodja的代码进行微小的调整。谢谢你的建议! – LeeO

我发现有人(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

+0

我讨厌分裂头发,但这不是你问的问题的答案......你似乎已经采用了维基例子并在你的参数中进行了拨号。 – jww

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

那么,你的问题的答案是,主要是。但请记住代码是作为wiki的示例编写的。


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

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); 
}