gpt4 book ai didi

c++ - Crypto++ pbkdf2 输出不同于 Rfc2898DeriveBytes (C#) 和 crypto.pbkdf2 (JavaScript)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:40:29 27 4
gpt4 key购买 nike

因此,我正在尝试使用 PBKDF2 在给定 256 位 base64 字符串的情况下派生 key 。我可以使用 C# 的 Rfc2898DeriveBytes 和节点加密的 pbkdf2 来派生相同的 key ,但是,我不能对 C++ 说同样的话。我不确定我是否进行了错误的转换或不正确地使用函数,但我会让你们看看。

C++

/* 256bit key */
string key = "Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ=";
string decodedKey;
StringSource(key, true, new Base64Decoder(new StringSink(decodedKey)));
const byte* keyByte = (const byte*) decodedKey.data();

/* Generate IV */
/*
AutoSeededRandomPool prng;
byte iv[AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
*/

/* FOR TESTING PURPOSES, HARDCODE IV */
string iv = "5iFv54dCRq5icQbD7QHQzg==";
string decodedIv;
StringSource(iv, true, new Base64Decoder(new StringSink(decodedIv)));
const byte* ivByte = (const byte *) decodedIv.data();

byte derivedKey[32];
PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf2;
pbkdf2.DeriveKey(derivedKey, 32, 0, keyByte, 32, ivByte, 16, 100);

/*
* derivedKey: 9tRyXCoQLTbUOLqm3M4OPGT6N25g+o0K090fVp/hflk=
*/

C#

// string key = "Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ="; // need to convert it to byte data
string key = Convert.FromBase64String("Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ="); // change above to this
RijndaelManaged symKey = new RijndaelManaged();
symKey.GenerateIV(); /* Assume hardcoded IV same as above */
Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes (key, symKey.IV, 100);

/*
* derivedKey: dZqBpZKyUPKn8pU4pyyeAw7Rg8uYd6yyj3WI1MIJSyc=
*/

JS

// var key = "Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ="; // need to convert it to byte data
var key = new Buffer("Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ=", "base64"); // changed above to this
var iv = crypto.randomBytes(16);
iv = "5iFv54dCRq5icQbD7QHQzg=="; /* HARDCODE IV */
crypto.pbkdf2(key, iv, 100, 32, function(err, derivedKey) { }

/*
* derivedKey: dZqBpZKyUPKn8pU4pyyeAw7Rg8uYd6yyj3WI1MIJSyc=
*/

Well the main questions is, what am I doing wrong on C++'s CryptoPP library that it is not deriving the same value.

解决方案:我是个笨蛋……在回顾了我在 JavaScript 和 C# 上的原始实现后,我意识到我错过了一个关键步骤,由于某种原因我没有收到编译器的投诉。基本上问题是我在 C# 和 JS 实现上的算法之前没有将使用的 key 转换为字节数据......

无论如何,建议的解决方案是:不要在凌晨 4 点编写代码,并确保数据转换一致...

我猜 TL;DR 是 C# 和 JS 将我的 256 位 key 转换为字节数据作为 ASCII 而不是 base64 转换。

最佳答案

Well the main questions is, what am I doing wrong on C++'s CryptoPP library that it is not deriving the same value.

好吧,我不认为你在使用 C++ 和 PBKDF2 的 C++ 中做错了什么。我认为其他库设置参数的方式不同,或者它们有点不标准。

我能够到达 IETF 的 test vectors for PBKDF2使用加密++:

// From https://www.ietf.org/rfc/rfc6070.txt
// PKCS #5: Password-Based Key Derivation Function 2 (PBKDF2) Test Vectors
//
// Input:
// P = "password" (8 octets)
// S = "salt" (4 octets)
// c = 1
// dkLen = 20
//
// Output:
// DK = 0c 60 c8 0f 96 1f 0e 71
// f3 a9 b5 24 af 60 12 06
// 2f e0 37 a6 (20 octets)

int main(int argc, char* argv[])
{
byte password[] ="password";
size_t plen = strlen((const char*)password);

byte salt[] = "salt";
size_t slen = strlen((const char*)salt);

int c = 1;
byte derived[20];

PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf2;
pbkdf2.DeriveKey(derived, sizeof(derived), 0, password, plen, salt, slen, c);

string result;
HexEncoder encoder(new StringSink(result));

encoder.Put(derived, sizeof(derived));
encoder.MessageEnd();

cout << "Derived: " << result << endl;

return 0;
}

然后运行程序:

$ ./cryptopp-test.exe
Derived: 0C60C80F961F0E71F3A9B524AF6012062FE037A6

我认为您应该做的第一件事是验证 C# 和 Javascript 实现是否使用与 Crypto++ 和 IETF 相同的字符编码。

如果不是,则检查 C# 和 Javascript 是否使用目的字节。 Crypto++ 没有,您可以在 pwdbased.h 查看实现.


不幸的是,当我输入你的参数时,我得到了一些不同的东西:

int main(int argc, char* argv[])
{
string t1 = "Y1Mjycd0+O+AendY5pB58JMlmS0EmBWgjdj2r2KW6qQ=";
string t2 = "5iFv54dCRq5icQbD7QHQzg==";

string pw, iv;

Base64Decoder b1(new StringSink(pw));
b1.Put((const byte*)t1.data(), t1.size());
b1.MessageEnd();

Base64Decoder b2(new StringSink(iv));
b2.Put((const byte*)t2.data(), t2.size());
b2.MessageEnd();

int c = 100;
byte derived[32];

cout << "pw size: " << pw.size() << endl;
cout << "iv size: " << iv.size() << endl;

PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf2;
pbkdf2.DeriveKey(derived, sizeof(derived), 0, (byte*)pw.data(), pw.size(), (byte*)iv.data(), iv.size(), c);

string result;
HexEncoder encoder(new StringSink(result));

encoder.Put(derived, sizeof(derived));
encoder.MessageEnd();

cout << "Derived: " << result << endl;

return 0;
}

运行结果:

$ ./cryptopp-test.exe
pw size: 32
iv size: 16
Derived: F6D4725C2A102D36D438BAA6DCCE0E3C64FA376E60FA8D0AD3DD1F569FE17E59

关于c++ - Crypto++ pbkdf2 输出不同于 Rfc2898DeriveBytes (C#) 和 crypto.pbkdf2 (JavaScript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27244449/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com