2012-12-09 14 views
10

Piszę program, aby zapoznać się z OpenSSL, libncurses i sieci UDP. Postanowiłem pracować z SHA256 OpenSSL, aby zapoznać się ze standardami szyfrowania w branży, ale mam problemy z jego działaniem. Izolowałem błąd związany z łączeniem OpenSSL z skompilowanym programem. Pracuję nad Ubuntu 12.10, 64-bitowym. Mam zainstalowany pakiet libssl-dev.Jak korzystać z funkcji SHA256 OpenSSL

Weźmy, na przykład, C++ main.cpp:

#include <iostream> 
#include <sstream> 
#include <string> 
#include <iomanip> 
using namespace std; 

#include <openssl/sha.h> 

string sha256(const string str) 
{ 
    unsigned char hash[SHA256_DIGEST_LENGTH]; 
    SHA256_CTX sha256; 
    SHA256_Init(&sha256); 
    SHA256_Update(&sha256, str.c_str(), str.size()); 
    SHA256_Final(hash, &sha256); 
    stringstream ss; 
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) 
    { 
     ss << hex << setw(2) << setfill('0') << (int)hash[i]; 
    } 
    return ss.str(); 
} 

int main() 
{ 

    cout << sha256("test") << endl; 
    cout << sha256("test2") << endl; 

    return 0; 

} 

używam funkcji SHA256() Znaleziono here jako otoczka do funkcjonalności sha256 OpenSSL.

Gdy próbuję skompilować z następującymi g ++ argumentów, pojawia się następujący błąd:

[email protected]:~/Programming/sha256$ g++ -lssl -lcrypto -o main main.cpp 
/tmp/ccYqwPUC.o: In function `sha256(std::string)': 
main.cpp:(.text+0x38): undefined reference to `SHA256_Init' 
main.cpp:(.text+0x71): undefined reference to `SHA256_Update' 
main.cpp:(.text+0x87): undefined reference to `SHA256_Final' 
collect2: error: ld returned 1 exit status 

Więc GCC wyraźnie rozpoznaje określone funkcje i rodzaje OpenSSL, ale ld się niepowodzeniem znaleźć symbole funkcyjne, o których mowa in sha.h.

Czy muszę ręcznie wskazywać konkretny obiekt lub katalog współdzielony?

Dzięki!

Odpowiedz

20

Popełniasz bardzo powszechny błąd początkujących ... Umieszczanie bibliotek, które łączysz w niewłaściwym miejscu w wierszu poleceń podczas kompilacji.

Zależności są odwrotne w linii poleceń, więc coś, co zależy od czegoś innego, powinno zostać umieszczone przed , od czego zależy od linii poleceń.

W przykładzie masz plik źródłowy main.cpp który zależy od pewnego zbioru bibliotek, a następnie plik źródłowy powinien być przed bibliotekami to zależy od:

$ g++ -o main main.cpp -lssl -lcrypto 

za bezpieczne, zawsze stawiamy biblioteki ostatni, po każdym pliku źródłowym lub obiektowym wymienionym w wierszu poleceń.

+0

Przez golly zadziałało! Dzięki! Używam GCC przez około 7 lat dla drobnych rzeczy, ale nigdy nie zdawałem sobie sprawy, że argumenty linii poleceń działają w ten sposób. – millinon

+2

po starcie '-o main'. bardzo niewiele programów uniksowych wymaga umieszczenia opcji po argumentach i ogólnie jest to zła praktyka IMO. –

+0

@jcomeau_ictx: Huh? Nie, to nie wystarczy. Powinien pójść za plikami źródłowymi, które odwołują się do symboli w tych bibliotekach. tj. "po" main.cpp "wystarczy. –

0

Działa to dobrze na moim komputerze, ale można spróbować:

extern "C" { 
#include <openssl/sha.h> 
} 

która mówi g ++, że wszystkie rzeczy w openssl/sha.h jest zadeklarowana jako funkcje „C”.

BTW, ile lat ma twój OpenSSL?

+0

Próbowałem tego, i używając powyższych argumentów GCC, nadal otrzymywałem te same błędy. Sugestia Joachima to naprawiła. Używam dla wersji OpenSSL w wersji 1.0.1c. – millinon