c++ - Crypto++ pbkdf2 output is different than Rfc2898DeriveBytes (C#) and crypto.pbkdf2 (JavaScript) -


so i'm trying use pbkdf2 derive key given base64 string of 256bits. able use c#'s rfc2898derivebytes , node-crypto's pbkdf2 derive same key, however, can't same c++. i'm not sure if i'm doing wrong conversions or using functions improperly, i'll let guys @ it.

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)); */  /* 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 convert byte data string key = convert.frombase64string("y1mjycd0+o+aendy5pb58jmlms0embwgjdj2r2kw6qq="); // change above rijndaelmanaged symkey = new rijndaelmanaged(); symkey.generateiv(); /* assume hardcoded iv same above */ rfc2898derivebytes derivedkey = new rfc2898derivebytes (key, symkey.iv, 100);  /*  * derivedkey: dzqbpzkyupkn8pu4pyyeaw7rg8uyd6yyj3wi1mijsyc=  */ 

js

// var key = "y1mjycd0+o+aendy5pb58jmlms0embwgjdj2r2kw6qq="; // need convert byte data var key = new buffer("y1mjycd0+o+aendy5pb58jmlms0embwgjdj2r2kw6qq=", "base64"); // changed above var iv = crypto.randombytes(16); iv = "5ifv54dcrq5icqbd7qhqzg=="; /* hardcode iv */ crypto.pbkdf2(key, iv, 100, 32, function(err, derivedkey) { }  /*  * derivedkey: dzqbpzkyupkn8pu4pyyeaw7rg8uyd6yyj3wi1mijsyc=  */ 

well main questions is, doing wrong on c++'s cryptopp library not deriving same value.

solution: being dumb... realized after review original implementation on javascript , c# missed crucial step reason did not complain compiler. problem did not convert key used byte data before algorithm on c# , js implementation...

anyways, proposed solution is: not code @ 4 , make sure consistent on data conversion...

i guess tl;dr of c# , js converting 256bit key byte data ascii instead of base64 conversion.

well main questions is, doing wrong on c++'s cryptopp library not deriving same value.

well, don't think doing wrong in c++ crypto++ , pbkdf2. think other libraries setting parameters differently, or tad-bit non-standard.

i able arrive @ ietf's test vectors pbkdf2 using crypto++:

// 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; } 

and run of program:

$ ./cryptopp-test.exe derived: 0c60c80f961f0e71f3a9b524af6012062fe037a6 

i think first thing should verify c# , javascript implementations using same character encoding crypto++ , ietf.

if that's not it, check see if c# , javascript use purpose byte. crypto++ not, , can see implementation @ pwdbased.h.


unfortunately, little different when dial in parameters:

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; } 

a run results in:

$ ./cryptopp-test.exe pw size: 32 iv size: 16 derived: f6d4725c2a102d36d438baa6dcce0e3c64fa376e60fa8d0ad3dd1f569fe17e59 

Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -