如何将 SecByteBlock 转换为字符串?
How to convert SecByteBlock to string?
我在尝试将 SecByteBlock
转换为字符串时遇到问题。
这是我的案例:
我想使用带有静态密钥和动态 iv 的 AES 加密用户访问数据。
我的代码是这样的:
AesKeyIvFactory aesKeyIvFactory;
SecByteBlock key = aesKeyIvFactory.loadKey();
SecByteBlock iv = aesKeyIvFactory.createIv();
encryptionService->encode(&userAccess, key, iv);
std::string token = std::string(iv.begin(), iv.end()) + userAccess;
上面的代码应该是:
从文件加载密钥;
创建 iv;
加密 (AES) 用户访问数据;
将 iv 与加密的用户数据访问连接起来以创建 "token";
运行一个测试几次,有时(1到10次)std::string(iv.begin(), iv.end())
不能正常工作。似乎在iv中有一个"line break"使转换失败。
我尝试了很多东西,但没有任何效果,而且我没有使用 c++ 的经验。
希望有人能帮助我。
I'm having a problem trying to convert SecByteBlock to string
如果问题在于从 SecByteBlock
及其 byte
数组到 std::string
及其 char
数组的转换,那么您应该:
SecByteBlock iv;
...
// C-style cast
std::string token = std::string((const char*)iv.data(), iv.size()) + userAccess;
或者,
SecByteBlock iv;
...
// C++-style cast
std::string token = std::string(reinterpret_cast<const char*>(iv.data()), iv.size()) + userAccess;
你也可以放弃赋值,只初始化然后追加:
SecByteBlock iv;
...
std::string token(reinterpret_cast<const char*>(iv.data()), iv.size());
...
std::string userAccess;
...
token += userAccess;
您可能遇到的另一个问题是 string
到 SecByteBlock
。你应该这样做:
std::string str;
...
// C-style cast
SecByteBlock sbb((const byte*)str.data(), str.size());
或:
std::string str;
...
// C++-style cast
SecByteBlock sbb(reinterpret_cast<const byte*>(str.data()), str.size());
我认为 Eric 回答了您关于如何将 SecByteBlock
转换为 std::string
的主要问题(包括 char*
和 byte*
之间的显式转换)。但是,您可以通过以下方式解决 std::string token = std::string(iv.begin(), iv.end()) + userAccess;
问题。
string token;
SecByteBlock iv(16), userAccess(16);
OS_GenerateRandomBlock(false, iv, iv.size());
OS_GenerateRandomBlock(false, userAccess, userAccess.size());
SecByteBlock nil;
nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH);
HMAC<SHA256> hmac;
hmac.SetKey(nil.data(), nil.size());
HashFilter filter(hmac, new HexEncoder(new StringSink(token)));
filter.Put(iv.data(), iv.size());
filter.Put(userAccess.data(), userAccess.size());
filter.MessageEnd();
cout << token << endl;
SecByteBlock nil
创建一个没有内存或大小的 object。 nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH)
大小并将 SecByteBlock
初始化为 0。否则,您有一个未初始化的内存块。
可以声明它并使用 0 初始化数组调整它的大小,但您必须熟悉来源,因为从 Crypto++ 5.6.2 开始它没有 Doxygen-docimented。那种方式是使用 NULL
指针,但大小不为 0。这是它的样子,但非常 non-intuitive:
SecByteBlock nil(NULL, HMAC<SHA256>::DEFAULT_KEYLENGTH);
这个技巧依赖于这个 SecBlock<T>
构造函数:
00250 SecBlock(const T *t, size_type len)
00251 : m_size(len)
00252 {
00253 m_ptr = m_alloc.allocate(len, NULL);
00254 if (t == NULL)
00255 memset_z(m_ptr, 0, len*sizeof(T));
00256 else
00257 memcpy(m_ptr, t, len*sizeof(T));
00258 }
如果可能,您应该使用 HKDF
而不是 HMAC<SHA>
和 nil
向量来从安全参数中提取熵。您可以在 HKDF class
的存储库中找到 HKDF
。它是独立的 header,因此它将 "just work"。
程序的典型 运行 具有 iv
和 userAccess
的随机值是:
$ ./cryptopp-test.exe
061CF705259058C4E01A2BF22830FC3F2A7E97F12FE605B38405B1E1B19A9E0F
另一种处理它的方法可能是基于 SecByteBlock
的 operator +=
的串联。结果是二进制字符串,而不是人类可读的 ASCII 字符串。
SecByteBlock result;
result += iv;
result += SecByteBlock(userAccess.data(), userAccess.size());
string token(result.data(), result.size());
如果你需要一个人类可读的字符串,那么 运行 它通过 HexEncoder
:
HexEncoder hex(new StringSink(token));
hex.Put(result.data(), result.size());
hex.MessageEnd();
但是它没有从参数中提取熵,所以我个人不太喜欢。
当您从 SecByteBlock
移动到 std::string
时,您实际上失去了安全分配器。这意味着副本中的数据在将数据输出到 string
object.
后不会被清零
HexEncoder
是一个方便的项目,它允许您转储二进制字符串。
另一个有用的可能是 Base64URLEncoder
。它使用网络安全字母表。
我在尝试将 SecByteBlock
转换为字符串时遇到问题。
这是我的案例:
我想使用带有静态密钥和动态 iv 的 AES 加密用户访问数据。 我的代码是这样的:
AesKeyIvFactory aesKeyIvFactory;
SecByteBlock key = aesKeyIvFactory.loadKey();
SecByteBlock iv = aesKeyIvFactory.createIv();
encryptionService->encode(&userAccess, key, iv);
std::string token = std::string(iv.begin(), iv.end()) + userAccess;
上面的代码应该是:
从文件加载密钥;
创建 iv;
加密 (AES) 用户访问数据;
将 iv 与加密的用户数据访问连接起来以创建 "token";
运行一个测试几次,有时(1到10次)std::string(iv.begin(), iv.end())
不能正常工作。似乎在iv中有一个"line break"使转换失败。
我尝试了很多东西,但没有任何效果,而且我没有使用 c++ 的经验。
希望有人能帮助我。
I'm having a problem trying to convert SecByteBlock to string
如果问题在于从 SecByteBlock
及其 byte
数组到 std::string
及其 char
数组的转换,那么您应该:
SecByteBlock iv;
...
// C-style cast
std::string token = std::string((const char*)iv.data(), iv.size()) + userAccess;
或者,
SecByteBlock iv;
...
// C++-style cast
std::string token = std::string(reinterpret_cast<const char*>(iv.data()), iv.size()) + userAccess;
你也可以放弃赋值,只初始化然后追加:
SecByteBlock iv;
...
std::string token(reinterpret_cast<const char*>(iv.data()), iv.size());
...
std::string userAccess;
...
token += userAccess;
您可能遇到的另一个问题是 string
到 SecByteBlock
。你应该这样做:
std::string str;
...
// C-style cast
SecByteBlock sbb((const byte*)str.data(), str.size());
或:
std::string str;
...
// C++-style cast
SecByteBlock sbb(reinterpret_cast<const byte*>(str.data()), str.size());
我认为 Eric 回答了您关于如何将 SecByteBlock
转换为 std::string
的主要问题(包括 char*
和 byte*
之间的显式转换)。但是,您可以通过以下方式解决 std::string token = std::string(iv.begin(), iv.end()) + userAccess;
问题。
string token;
SecByteBlock iv(16), userAccess(16);
OS_GenerateRandomBlock(false, iv, iv.size());
OS_GenerateRandomBlock(false, userAccess, userAccess.size());
SecByteBlock nil;
nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH);
HMAC<SHA256> hmac;
hmac.SetKey(nil.data(), nil.size());
HashFilter filter(hmac, new HexEncoder(new StringSink(token)));
filter.Put(iv.data(), iv.size());
filter.Put(userAccess.data(), userAccess.size());
filter.MessageEnd();
cout << token << endl;
SecByteBlock nil
创建一个没有内存或大小的 object。 nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH)
大小并将 SecByteBlock
初始化为 0。否则,您有一个未初始化的内存块。
可以声明它并使用 0 初始化数组调整它的大小,但您必须熟悉来源,因为从 Crypto++ 5.6.2 开始它没有 Doxygen-docimented。那种方式是使用 NULL
指针,但大小不为 0。这是它的样子,但非常 non-intuitive:
SecByteBlock nil(NULL, HMAC<SHA256>::DEFAULT_KEYLENGTH);
这个技巧依赖于这个 SecBlock<T>
构造函数:
00250 SecBlock(const T *t, size_type len)
00251 : m_size(len)
00252 {
00253 m_ptr = m_alloc.allocate(len, NULL);
00254 if (t == NULL)
00255 memset_z(m_ptr, 0, len*sizeof(T));
00256 else
00257 memcpy(m_ptr, t, len*sizeof(T));
00258 }
如果可能,您应该使用 HKDF
而不是 HMAC<SHA>
和 nil
向量来从安全参数中提取熵。您可以在 HKDF class
的存储库中找到 HKDF
。它是独立的 header,因此它将 "just work"。
程序的典型 运行 具有 iv
和 userAccess
的随机值是:
$ ./cryptopp-test.exe
061CF705259058C4E01A2BF22830FC3F2A7E97F12FE605B38405B1E1B19A9E0F
另一种处理它的方法可能是基于 SecByteBlock
的 operator +=
的串联。结果是二进制字符串,而不是人类可读的 ASCII 字符串。
SecByteBlock result;
result += iv;
result += SecByteBlock(userAccess.data(), userAccess.size());
string token(result.data(), result.size());
如果你需要一个人类可读的字符串,那么 运行 它通过 HexEncoder
:
HexEncoder hex(new StringSink(token));
hex.Put(result.data(), result.size());
hex.MessageEnd();
但是它没有从参数中提取熵,所以我个人不太喜欢。
当您从 SecByteBlock
移动到 std::string
时,您实际上失去了安全分配器。这意味着副本中的数据在将数据输出到 string
object.
HexEncoder
是一个方便的项目,它允许您转储二进制字符串。
另一个有用的可能是 Base64URLEncoder
。它使用网络安全字母表。