C++ PKCS5_PBKDF2_HMAC的盐与iv

C++ PKCS5_PBKDF2_HMAC的盐与iv,c++,cryptography,crypto++,C++,Cryptography,Crypto++,理解PKCS5_PBKDF2_HMAC()需要一个salt,并返回一个派生密钥 而GCM::Encryption.SetKeyWithIV()需要iv(以及派生密钥) 在PKCS5\u PBKDF2\u HMAC())和iv(在GCM::Encryption.SetKeyWithIV())中使用相同的值安全吗?或者它们应该不同吗 salt(在PKCS5_PBKDF2_HMAC()中)和iv(在GCM::Encryption.SetKeyWithIV()中)使用相同的值安全吗?或者它们应该不同吗

理解
PKCS5_PBKDF2_HMAC()
需要一个salt,并返回一个派生密钥

GCM::Encryption.SetKeyWithIV()
需要iv(以及派生密钥)

PKCS5\u PBKDF2\u HMAC()
)和iv(在
GCM::Encryption.SetKeyWithIV()
)中使用相同的值安全吗?或者它们应该不同吗

salt(在PKCS5_PBKDF2_HMAC()中)和iv(在GCM::Encryption.SetKeyWithIV()中)使用相同的值安全吗?或者它们应该不同吗

是和否。是-您可以使用PKCS5_PBKDF2_HMAC的输出生成salt、iv或密钥。否-您不应该重复使用这样的参数

通常,你会做下面这样的事情。它使用唯一的标签,因此派生参数不能相同

string password = "super secret password;
string label = "Key derivation with IV";
size_t length = password.length() + label.length();
unsigned int count = 5000;

SecByteBlock key(32 /*Key*/ + 16 /*IV*/);

PKCS5_PBKDF2_HMAC<SHA1> pbkdf2;
pbkdf2.DeriveKey(key, key.size(), 0, (unsigned char*)(password + label).data(), length,
    NULL /*salt*/, 0 /*salt length*/, count);

GCM<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key, 32, key+32, 16);
string password=“超级机密密码;
string label=“带IV的键派生”;
size_t length=password.length()+label.length();
无符号整数计数=5000;
SecByteBlock密钥(32/*密钥*/+16/*IV*/);
PKCS5_PBKDF2_HMAC PBKDF2;
pbkdf2.DeriveKey(key,key.size(),0,(无符号字符*)(密码+标签).data(),长度,
空/*盐*/,0/*盐长度*/,计数);
GCM::加密机;
加密机。SetKeyWithIV(密钥,32,密钥+32,16);
上面的标签有助于使派生唯一

如果为某个salt派生,则标签可能是
“X的salt派生”
。在这种情况下,您将从KDF获得不同的值


在上面的例子中,可以应用KDF两次。首先,在不含盐的情况下应用KDF以创建盐(使用唯一标签)。其次,使用盐来派生密钥和iv(使用先前生成的盐和唯一标签).

实际上,我会在每次加密时随机设置标签,但将其与密文一起存储在明文中-基本上就像iv/salt一样使用它(但仍然只需要存储该值-因为另一个iv将从KDF派生)?@David-是的,那也应该没问题。这是我最后得到的结果…我尝试让它少用std::string,因为看到它并认为它是原始字节会让我感到困惑;)(ByteArray只是一个结构,用于保存指针和数据长度,并在删除时释放数据)我不太清楚如何使用BitBucket或ArraySink来代替StringSink,所以留下了这一部分in@David-
BitBucket
是一个简单地丢弃输出的接收器。它就像向
/dev/null
发送一些东西一样。