1. 使用OpenSSL內置的數據結構BIO可以方便的創建安全和非安全鏈接,
在IBM Web上的"使用OpenSSL進行安全編程"系列的三篇文章是個不錯的入門:
http://www.ibm.com/developerworks/cn/linux/l-openssl.htmlhttp://www.ibm.com/developerworks/cn/linux/l-openssl2.htmlhttp://www.ibm.com/developerworks/cn/linux/l-openssl3.html 安全鏈接的簡要概述:
安全連接要求在連接建立后進行握手。在握手過程中,服務器向客戶機發送一個證書, 然后,客戶機根據一組可信任證書來核實該證書。它還將檢查證書,以確保它沒有過期。要 檢驗證書是可信任的,需要在連接建立之前提前加載一個可信任證書庫。
只有在服務器發出請求時,客戶機才會向服務器發送一個證書。該過程叫做客戶機認證。使用證書, 在客戶機和服務器之間傳遞密碼參數,以建立安全連接。盡管握手是在建立連接之后才進行的,但是客戶機或服務器可以在任何時刻請求進行一次新的握手。
附帶兩個Demo:分別是使用BIO建立普通的socket鏈接和ssl鏈接, 并下載google得主頁.
1
#include "openssl/ssl.h"
2
#include "openssl/bio.h"
3
#include "openssl/err.h"
4
5
6
#include <iostream>
7
#include <winsock2.h>
8
9
10
#pragma comment( lib, "ws2_32.lib" )
11
#pragma comment( lib, "libeay32.lib" )
12
#pragma comment( lib, "ssleay32.lib" )
13
14
15
int main( int argc, char* argv[] )
{
16
/**/////////////
17
// 初始化 //
18
/**/////////////
19
BIO* bio;
20
int ret;
21
char* request = "GET / HTTP/1.1\x0D\x0AHost: www.google.com\x0D\x0A\x43onnection: Close\x0D\x0A\x0D\x0A";
22
char buf[1024];
23
24
ERR_load_BIO_strings();
25
SSL_load_error_strings();
26
SSLeay_add_ssl_algorithms();
27
28
29
/**///////////////
30
// 建立鏈接 //
31
/**///////////////
32
33
bio = BIO_new_connect("www.google.com:80");
34
if(bio == NULL)
{
35
std::cout<<"BIO_new_connect error."<<std::endl;
36
return -1;
37
}
38
39
if(BIO_do_connect(bio) <= 0)
{
40
std::cout<<"BIO_new_connect error."<<std::endl;
41
BIO_free_all(bio);
42
return -1;
43
}
44
45
// 發送請求
46
BIO_write(bio, request, strlen(request));
47
48
// 接收數據
49
for(;;)
{
50
ret = BIO_read(bio, buf, 1023);
51
if(ret <= 0)
{
52
break;
53
}
54
buf[ret] = 0;
55
std::cout<<buf<<std::endl;
56
}
57
58
BIO_free_all(bio);
59
return 0;
60
}
1
#include "openssl/ssl.h"
2
#include "openssl/bio.h"
3
#include "openssl/err.h"
4
5
6
#include <iostream>
7
#include <winsock2.h>
8
9
10
#pragma comment( lib, "ws2_32.lib" )
11
#pragma comment( lib, "libeay32.lib" )
12
#pragma comment( lib, "ssleay32.lib" )
13
14
// 我們默認對服務器的證書都是可信的,沒有進行服務器證書的驗證.
15
int main( int argc, char* argv[] )
{
16
/**/////////////
17
// 初始化 //
18
/**/////////////
19
SSL* ssl;
20
SSL_CTX* ctx;
21
22
BIO* bio;
23
int ret;
24
char* request = "GET / HTTP/1.1\x0D\x0AHost: www.google.com\x0D\x0A\x43onnection: Close\x0D\x0A\x0D\x0A";
25
char buf[1024];
26
27
ERR_load_BIO_strings();
28
SSL_load_error_strings();
29
SSLeay_add_ssl_algorithms();
30
31
ctx = SSL_CTX_new ( SSLv23_client_method() );
32
if (!ctx)
{
33
ERR_print_errors_fp(stderr);
34
std::cout<<"SSL_CTX_new error."<<std::endl;
35
return -1;
36
}
37
38
/**///////////////
39
// 建立鏈接 //
40
/**///////////////
41
bio = BIO_new_ssl_connect(ctx);
42
BIO_get_ssl(bio, & ssl);
43
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
44
BIO_set_conn_hostname(bio, "www.google.com:443");
45
if(BIO_do_connect(bio) <= 0)
{
46
std::cout<<"BIO_do_connect error."<<std::endl;
47
return -1;
48
}
49
50
51
// 發送請求
52
BIO_write(bio, request, strlen(request));
53
54
// 接收數據
55
for(;;)
{
56
ret = BIO_read(bio, buf, 1023);
57
if(ret <= 0)
{
58
break;
59
}
60
buf[ret] = 0;
61
std::cout<<buf<<std::endl;
62
}
63
64
BIO_free_all(bio);
65
SSL_CTX_free(ctx);
66
return 0;
67
}
68