如何使用 Crypto++ 库创建 HMAC 256?
How to create a HMAC 256 using the Crypto++ library?
我有一个字符串需要使用 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;
提供的示例有效,但似乎做了很多事情。我只想做的是:
- 取一个字符串:"GreatWallOfChina"
- 密钥:m2hspk1ZxsjlsDU6JhMvD3TQQhm+zOwab3slKEILoSSnfk3b2+NUyeJiCrRAJ/D3V5y+QDZaIqRx9q9siMopaA==
- 将密钥转换为 base64:bTJoc3BrMVp4c2psc0RVNkpoTXZEM1RRUWhtK3pPd2FiM3NsS0VJTG9TU25mazNiMitOVXllSmlDclJBSi9EM1Y1eStrRRFphSXFSeDlxOXNpTW9wYUE9PQ==
- 使用该 base64 密钥创建 hmac256。
所以,我的问题是,上面示例代码中的所有步骤都是必要的吗? (字节块声明、十六进制编码等)
如果这是一个非常菜鸟的问题,我们深表歉意。
不,您上面的步骤当然不是必需的,例如 base 64 编码已经 base 64 编码的值。
Crypto++ 主要基于带有接收器和源的流式传输。这就是库的设置方式,但对于小型计算来说,它会有些冗长。
请注意,大部分示例代码只是生成密钥并打印明文、密钥和身份验证标记(MAC 值)和一些异常处理。所需的代码基本上就在 try
/ catch
块内。
我发现其他人 (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;
}
So, my question is, are all the steps in the example code above necessary?
好吧,你的问题的答案大多是肯定的。但请记住,代码是作为 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);
}
我有一个字符串需要使用 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;
提供的示例有效,但似乎做了很多事情。我只想做的是:
- 取一个字符串:"GreatWallOfChina"
- 密钥:m2hspk1ZxsjlsDU6JhMvD3TQQhm+zOwab3slKEILoSSnfk3b2+NUyeJiCrRAJ/D3V5y+QDZaIqRx9q9siMopaA==
- 将密钥转换为 base64:bTJoc3BrMVp4c2psc0RVNkpoTXZEM1RRUWhtK3pPd2FiM3NsS0VJTG9TU25mazNiMitOVXllSmlDclJBSi9EM1Y1eStrRRFphSXFSeDlxOXNpTW9wYUE9PQ==
- 使用该 base64 密钥创建 hmac256。
所以,我的问题是,上面示例代码中的所有步骤都是必要的吗? (字节块声明、十六进制编码等)
如果这是一个非常菜鸟的问题,我们深表歉意。
不,您上面的步骤当然不是必需的,例如 base 64 编码已经 base 64 编码的值。
Crypto++ 主要基于带有接收器和源的流式传输。这就是库的设置方式,但对于小型计算来说,它会有些冗长。
请注意,大部分示例代码只是生成密钥并打印明文、密钥和身份验证标记(MAC 值)和一些异常处理。所需的代码基本上就在 try
/ catch
块内。
我发现其他人 (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;
}
So, my question is, are all the steps in the example code above necessary?
好吧,你的问题的答案大多是肯定的。但请记住,代码是作为 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);
}