2012-12-09 41 views
10

Tôi đang viết một chương trình để làm quen với OpenSSL, libncurses và mạng UDP. Tôi quyết định làm việc với SHA256 của OpenSSL để trở nên quen thuộc với các tiêu chuẩn mã hóa ngành, nhưng tôi đang gặp vấn đề với việc làm việc đó. Tôi đã bị cô lập lỗi để liên kết của OpenSSL với chương trình biên soạn. Tôi đang làm việc trên Ubuntu 12,10, 64 bit. Tôi đã cài đặt gói libssl-dev.Cách sử dụng các chức năng SHA256 của OpenSSL

Lấy ví dụ, 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; 

} 

Tôi đang sử dụng SHA256() chức năng tìm thấy here như là một wrapper cho các chức năng SHA256 OpenSSL của.

Khi tôi cố gắng để biên dịch với các đối số g sau ++, tôi nhận được lỗi sau:

[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 

Vì vậy, GCC công nhận rõ ràng chức năng và các loại định nghĩa OpenSSL, nhưng ld là thất bại trong việc tìm những biểu tượng chức năng gọi trong sha.h.

Tôi có cần trỏ theo cách thủ công đến một đối tượng hoặc thư mục được chia sẻ cụ thể không?

Cảm ơn!

Trả lời

20

Bạn mắc lỗi người mới bắt đầu rất phổ biến ... Đặt các thư viện bạn liên kết với sai vị trí trên dòng lệnh khi bạn xây dựng.

Các phụ thuộc được đảo ngược trên dòng lệnh, do đó, điều gì đó phụ thuộc vào một thứ khác thực sự nên được đặt trước điều gì tùy thuộc vào dòng lệnh.

Trong ví dụ của bạn, bạn có một nguồn tập tin main.cpp mà phụ thuộc vào một số bộ thư viện, sau đó tập tin nguồn nên trước khi các thư viện nó phụ thuộc vào:

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

Để được an toàn, thư viện luôn đặt cuối cùng, sau bất kỳ tệp nguồn hoặc đối tượng nào được liệt kê trên dòng lệnh.

+0

Bởi golly, nó đã hoạt động! Cảm ơn! Tôi đã sử dụng GCC trong khoảng 7 năm cho những điều nhỏ nhặt, nhưng tôi chưa bao giờ nhận ra rằng các đối số dòng lệnh hoạt động như thế. – millinon

+2

sau khi '-o' chính là đủ. rất ít chương trình Unix yêu cầu bạn đặt các tùy chọn sau các đối số, và nói chung đó là một IMO thực hành không tốt. –

+0

@jcomeau_ictx: Huh? Không, không đủ. Nó nên đi sau khi các tập tin nguồn tham chiếu các ký hiệu trong các thư viện đó. tức là "sau khi' main.cpp' là đủ ". –

0

này hoạt động tốt trên hệ thống của mình, nhưng bạn có thể thử:

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

mà nói với g ++ rằng tất cả những thứ trong openssl/sha.h được khai báo là chức năng "C".

BTW, OpenSSL của bạn bao nhiêu tuổi?

+0

Tôi đã thử và sử dụng các đối số GCC ở trên, tôi vẫn nhận được các lỗi giống nhau. Đề nghị của Joachim đã sửa nó. Tôi đang sử dụng phiên bản OpenSSL 1.0.1c, để lưu nội dung. – millinon

Các vấn đề liên quan