我想用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;
但是std::cout
盐似乎不是一个合适的字符串(包含控制符号和其他东西)。这很可能只是我的错。
我是否使用OpenSSL的错误功能来生成随机数据?
或者是我从buf
转换为字符串错误?
答案 0 :(得分:2)
随机数据是随机数据。这就是你所要求的,而这正是你所得到的。您的salt
变量是恰当的字符串,恰好包含不可打印的字符。如果你想拥有可打印的字符,实现这一目的的一种方法是使用base64编码,但这会炸掉它的长度。另一个选择是以某种方式丢弃不可打印的字符,但我没有看到任何强制RAND_bytes
执行此操作的机制。我想你可以简单地在循环中获取随机字节,直到你得到length
可打印字符。
如果您可以接受编码base64,下面是一个如何使用从Joe Linoff Cipher library中提取的OpenSSL base64编码器的示例:
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
开关。