c++ - 如何从 OpenSSL 中获取随机盐作为 std::string

标签 c++ c++11 random openssl salt

我想用 OpenSSL 生成一个随机字符串,然后将其用作散列函数中的盐(将是 Argon2)。目前我正在以这种方式生成随机数据:

if(length < CryptConfig::sMinSaltLen){        
    return 1;
}
if (!sInitialized){
    RAND_poll();
    sInitialized = true;
}

unsigned char * buf = new unsigned char[length];
if (!sInitialized || !RAND_bytes(buf, length)) {      
    return 1;
}

salt = std::string (reinterpret_cast<char*>(buf));
delete buf;

return 0;

但是 salt 的 std::cout 似乎不是正确的字符串(包含控制符号和其他内容)。这很可能只是我的错。

我是否使用了错误的 OpenSSL 函数来生成随机数据?

或者我从 buf 到字符串的转换有问题吗?

最佳答案

随机数据就是随机数据。这就是您所要求的,而这正是您所得到的。您的 salt 变量是一个适当的字符串,恰好包含不可打印的字符。如果你希望有可打印的字符,实现它的一种方法是使用 base64 编码,但这会增加它的长度。另一种选择是以某种方式丢弃不可打印的字符,但我没有看到任何强制 RAND_bytes 执行此操作的机制。我想您可以简单地在循环中获取随机字节,直到获得 length 可打印字符。

如果您可以接受 base64 编码,这里有一个如何使用 OpenSSL base64 编码器的示例,摘自 Joe Linoff 的 Cipher library :

string Cipher::encode_base64(uchar* ciphertext,
                 uint   ciphertext_len) const
{
  DBG_FCT("encode_base64");
  BIO* b64 = BIO_new(BIO_f_base64());
  BIO* bm  = BIO_new(BIO_s_mem());
  b64 = BIO_push(b64,bm);
  if (BIO_write(b64,ciphertext,ciphertext_len)<2) {
    throw runtime_error("BIO_write() failed");
  }
  if (BIO_flush(b64)<1) {
    throw runtime_error("BIO_flush() failed");
  }
  BUF_MEM *bptr=0;
  BIO_get_mem_ptr(b64,&bptr);
  uint len=bptr->length;
  char* mimetext = new char[len+1];
  memcpy(mimetext, bptr->data, bptr->length-1);
  mimetext[bptr->length-1]=0;
  BIO_free_all(b64);

  string ret = mimetext;
  delete [] mimetext;
  return ret;
}

对于这段代码,我建议添加 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL),否则您将在每 64 个字符后插入一个换行符。有关详细信息,请参阅 OpenSSL 的 -A 开关。

关于c++ - 如何从 OpenSSL 中获取随机盐作为 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35102371/

相关文章:

java - 如何在 Java 中复制此 C++ 枚举开关?

派生类中非虚函数的 C++ 同名与 `final` 说明符冲突

具有非均匀离散密度的随机数

C++子类访问修饰符?

c++ - 模板类的模板成员函数特化,无需指定类模板参数

c++ - 带有 memset_s 分配器的 std::vector

c++ - remove_reference 如何禁用模板参数推导?

c++ - 编译时检查 trait specialization 是否有唯一的 id

objective-c - Objective-C 中的非重复随机数

haskell - Haskell 中两个 `LocalTime` (或 `UTCTime` )之间的随机时间