Vzácný pád s Crypto ++ PBKDF2 :: DeriveKey ()

hlasů
1

Já používám knihovnu CryptoPP hash několik hesel. Asi 1 z 10 krát, dojde k chybě na řádku pod DeriveKey s segfault.

I při použití pevných parametrů dojde k chybě stále se zdá náhodný. Zajímalo by mě, jestli snad potřebuji ‚\ 0‘ na konci svých řetězcích. Anebo výstupní buffer potřebuje být nula inicializace, nebo tak něco?

Každopádně, tady je kód.

#include <cryptopp/aes.h>
#include <cryptopp/algparam.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <cryptopp/sha.h>
#include <cryptopp/pwdbased.h>

int main()
{
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256> pbkdf2;

CryptoPP::byte salt[16];

CryptoPP::byte key[32];

/* Hard coded for testing purposes */
Common::podFromHex(00f8807a289655b2a8e38cda00182a32, salt);

/* Hard coded for testing purposes */
std::string password = a;

std::cout << Salt:  << Common::podToHex(salt) << std::endl;
std::cout << Salt size:  << sizeof(salt) << std::endl;
std::cout << Password:  << password.data() << std::endl;
std::cout << Password size:  << password.size() << std::endl;

/* Rare segfault on this line */
pbkdf2.DeriveKey(
    key, sizeof(key), 0, (CryptoPP::byte *)password.data(),
    password.size(), salt, sizeof(salt), Constants::PBKDF2_ITERATIONS
);
}

Všechno se zdá být správně inicializovat - tiskové prohlášení mi přesně to samé pokaždé:

Salt: 00f8807a289655b2a8e38cda00182a32
Salt size: 16
Password: a
Password size: 1

Kromě toho - za hash hesla je použitelný, když to není segfault. Jsem pomocí šifrování AES později, a mohu dokonale šifrování zrušit soubor, a všechna data, jak se očekávalo.

Zdrojový kód k odvození klíče lze nalézt zde, mimochodem: https://www.cryptopp.com/docs/ref/pwdbased_8h_source.html#l00235

Dík.

Položena 07/11/2018 v 23:36
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
3

Já hazarding hádat, ale saltnení NULL ukončen. Program je pravděpodobně přístup mimo 16. prvku saltpole:

std::cout << "Salt: " << Common::podToHex(salt) << std::endl;

Vkládá se provádí několikrát bez problémů. Je to váš program méně volání na společné knihovny.

Volání std::memcpypouze bere nejvíce vlevo 16-bajtů řetězce. To nedělá konverzi. (Jen jsem chtěl, aby se odstranily volání Common).

$ cat test.cxx

#include "cryptlib.h"
#include "filters.h"
#include "sha.h"
#include "hex.h"
#include "files.h"
#include "pwdbased.h"

#include <string>
#include <iostream>
#include <cstring>

int main()
{
    using namespace CryptoPP;

    PKCS5_PBKDF2_HMAC<SHA256> pbkdf2;

    byte salt[16], key[32];

    /* Hard coded for testing purposes */
    // Common::podFromHex("00f8807a289655b2a8e38cda00182a32", salt);
    std::memcpy(salt, "00f8807a289655b2a8e38cda00182a32", 16);

    /* Hard coded for testing purposes */
    std::string password = "a";

    // std::cout << "Salt: " << Common::podToHex(salt) << std::endl;
    std::cout << "Salt: ";
    StringSource(salt, sizeof(salt), true, new HexEncoder(new FileSink(std::cout)));
    std::cout << std::endl;

    std::cout << "Salt size: " << sizeof(salt) << std::endl;
    std::cout << "Password: " << password.data() << std::endl;
    std::cout << "Password size: " << password.size() << std::endl;

    /* Rare segfault on this line */
    pbkdf2.DeriveKey(
        key, sizeof(key), 0, (byte *)password.data(),
        password.size(), salt, sizeof(salt), 10000 /*Constants::PBKDF2_ITERATIONS*/
    );

    std::cout << "Key: ";
    StringSource(key, sizeof(key), true, new HexEncoder(new FileSink(std::cout)));
    std::cout << std::endl;

    return 0;
}

Zkompilovaný a provedeny s:

$ g++ -DNDEBUG -g2 -O3 test.cxx -o test.exe ./libcryptopp.a
$ ./test.exe
Salt: 30306638383037613238393635356232
Salt size: 16
Password: a
Password size: 1
Key: F88BA6947B802C66F7E7A2BC0099AFD92C81DC293E3CC48C2DA3FA75E27ECE6B
Odpovězeno 08/11/2018 v 05:12
zdroj uživatelem

hlasů
0

Skončil jsem, kterým se to. Nebylo to vlastně kvůli některé z kódu uvedené výše, ale to bylo proto, že jsem byl volání funkce pomocí tohoto, v manipulátoru signálu.

Protože tento bral nějakou dobu ke spuštění (pomocí 500,000 iterací), to vypadalo, že bude shazovat tady pokaždé, ale to bylo vlastně není vzhledem k této lince.

Skončil jsem, kterým se to hodit vlajku bool v obsluze signálu, a má vlastní vlákno pozoruje tu vlajku. Když byl nastaven příznak, že se nazývá destruktor, což vyvolalo normální vypnutí proudu, což umožňuje všem svým závity na odstavení a uložení správně.

Odpovězeno 13/11/2018 v 03:18
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more