最近项目需要,花了三天研究了下openssl,这里做个记录
SSL的具体内容网上多的事,可以自行google,这里主要记录自己的理解
SSL的具体任务可以有两点:
1.证书的验证
2.加密套件和加密信息的协商
解释1: 所谓证书的验证,就是说,在SSL进行握手的时候,客户端和服务端相互证明自己身份的一种方式。
举个例子,我和小三需要进行沟通,那我需要和她协商一个我们两个都知道的方式(或者是加密方法)让她能将我发给她的信息进行解密,而让别的人看到了不知道我们在说什么。这个就是第2点的解释。那小三在接受到了我的消息并解密后,她时怎么知道这个信息就是由我给她的呢,难道不会是我老婆逼问我加密信息后用我的手机给她发的吗? 所以这个时候就需要证书验证这个步骤,来验证我是我。那这时候我就会比如和她之前商量好,从我们两个都信任的一个人那里拿了一件信物,只有我和她在交换信息之前,把这个发给她,她看到后,才能确定这个发给她信息的人就是我。
解释2: 第2点就是我上一点中所提到到,这次对于加密套件不做解释,以后有机会研究深入再做总结
看下图:
从图上看,服务端把证书发给了客户端,客户端对服务端的证书进行验证,验证过程就是查看服务端的证书链中的证书客户端本地是不是承认它。发现所有的证书和root证书时客户端认可的之后,就可以拿这个服务端的公钥进行数据的加密发送给服务端(这里的加密不是最终的加密信息,这里就牵涉到ssl的加密套件协商,以后有机会再详解下这块)
以上就是ssl进行证书验证的原理了。接下来用openssl这个工具来实现下证书的认证:
直接上代码:
-
int main(int argc,char **argv)
-
{
-
int socketfd;
-
struct sockaddr_in dest;
-
-
SSL_CTX *ctx;
-
SSL *ssl;
-
-
SSL_library_init();
-
OpenSSL_add_all_algorithms();
-
SSL_load_error_strings();
-
ctx = SSL_CTX_new(SSLv23_client_method());
-
if(ctx == NULL)
-
{
-
ERR_print_errors_fp(stdout);
-
exit(1);
-
}
-
-
int num = SSL_CTX_load_verify_locations(ctx,“./cer/cafile.pem”,NULL);
-
if(num != 1)
-
{
-
std::cout<<"Load locations error"<<std::endl;
-
return 0;
-
}
-
printf("num is %d\n",num);
-
-
if((socketfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
-
{
-
perror("Socket");
-
exit(errno);
-
}
-
printf("Socket create\n");
-
-
char str[32] = {0};
-
struct hostent* m_host = NULL;
-
m_host = gethostbyname("google.com.hk");
-
//m_host = gethostbyname("msl2.visualon.local");
-
//m_host = gethostbyname("hls.ftgroup-devices.com");
-
char **pptr = m_host->h_addr_list;
-
if(pptr == NULL)
-
{
-
std::cout<<"get addr_list error"<<std::endl;
-
}
-
for(;*pptr != NULL;pptr++)
-
{
-
inet_ntop(m_host->h_addrtype, *pptr, str, sizeof(str));
-
}
-
std::cout<<"ip address is "<<str<<std::endl;
-
memset(&dest,0,sizeof(dest));
-
dest.sin_family = AF_INET;
-
dest.sin_addr.s_addr = inet_addr(str);
-
dest.sin_port = htons(443);
-
socklen_t len = sizeof(dest);
-
printf("address creat\n");
-
-
if(connect(socketfd,(struct sockaddr*)(&dest),len) != 0)
-
{
-
perror("Connect ");
-
exit(errno);
-
}
-
printf("Server Connected\n");
-
-
-
ssl = SSL_new(ctx);
-
SSL_set_fd(ssl,socketfd);
-
if(SSL_connect(ssl) == -1)
-
{
-
ERR_print_errors_fp(stderr);
-
}
-
else
-
{
-
printf("Connected with %s encryption\n",SSL_get_cipher(ssl));
-
}
-
int ret = SSL_get_verify_result(ssl);
-
std::cout<<"crt verify data is "<<ret<<std::endl;
-
int geterror = ERR_get_error();
-
std::cout<<"geterror is "<<geterror<<std::endl;
-
-
}
运行结果:
crt verify data is 0
可以看出验证通过了。
想要看看具体的验证过程我们可以用openssl的命令行工具进行测试:
-
./openssl s_client -connect www.google.com:443 -CAfile ../TestCase/cer/cafile.pem
这里cafile.pem是什么文件我们稍后再说,先看结果:
-
CONNECTED(00000003)
-
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
-
verify return:1
-
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
-
verify return:1
-
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
-
verify return:1
-
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
-
verify return:1
-
---
-
Certificate chain
-
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
-
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
-
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
-
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
-
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
-
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-
---
-
Server certificate
-
-----BEGIN CERTIFICATE-----
-
MIIEdjCCA16gAwIBAgIIB1Qnfj/zM4IwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
-
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
-
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwNjAzMDkyNjAxWhcNMTUwOTAxMDAwMDAw
-
WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
-
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOd3d3
-
Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChruJu
-
4vl1I+x9Ypzejv0NsDYfAChaaOH4jjjv33IhuYkJsh8yyjCKBj6I2z2eCBwctzoT
-
Wcv73rUwGI+nyevtksAWemIbWssurCfwg9su/8TIg4i61T7R7RefnrVzbNcTiVsD
-
73wcItdJdJHSef9rjmISeEUOVl8Bf0jJ9FcJ7fOAvZ1FI5QBCKZqaThqw/Yueseh
-
ZJVjK//XYZJXNJzx3u+Esjctqk/+qyOiPkAWdpr/hkIfO6+94lfWqNTu1tnscPXt
-
hUtFJI0g5O3IY3iQKZArfP9Z4CnJewBR4YZWh5ON5Kl8f3qz/MZkluxcpPXNi81C
-
5VIGfIQX24iiISihAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
-
KwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYBBQUHAQEE
-
XDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0
-
MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0G
-
A1UdDgQWBBQbxIwppiAAgZarS9XPgPHhburQJDAMBgNVHRMBAf8EAjAAMB8GA1Ud
-
IwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYKKwYBBAHW
-
eQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB
-
RzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBcNNydftmGqg/r2wtLrvGJMG9fkLAT
-
Fl0SaUFAPzdbUrOF+TEmub8TA8RJVcZC7qrpyHOIbi92Fku1IFTzbMoWicxTxriY
-
JRyz7genbKaNjUY/2eiGS41zuVB+LDNg5k9UBKrPtJtI8g3myg/aq6N+e348RAfD
-
wrpt/cYJw1oli1Qr93Wdqnb7sG8jk1f2W8TFK/0D2/5mQsr8SExDR9vLehC6kf4u
-
TleWRVLvKFFcCPd/mhnlD7zTl6p77q/+7kpOJiEYigBiv0Yax769MG6r6YuEPjlB
-
GEOKUhNxGbmLSVRrmfedg3RpYQFoZmN2ML8YANX3JWwE7lDpWSCRVo0z
-
-----END CERTIFICATE-----
-
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
-
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
-
---
-
No client certificate CA names sent
-
---
-
SSL handshake has read 3719 bytes and written 445 bytes
-
---
-
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
-
Server public key is 2048 bit
-
Secure Renegotiation IS supported
-
Compression: NONE
-
Expansion: NONE
-
SSL-Session:
-
Protocol : TLSv1.2
-
Cipher : ECDHE-RSA-AES128-GCM-SHA256
-
Session-ID: 4A0A7F5444A07A452BF76BA0C62F970D3C10007B0D358228358CA7B44B725909
-
Session-ID-ctx:
-
Master-Key: C1DA57F55CBB39EA24AE26CFD32778AD9B7BF0F09518822DB98047DFD937BEF3A0D88484BFC11C2EA5532C310B26EB58
-
Key-Arg : None
-
PSK identity: None
-
PSK identity hint: None
-
SRP username: None
-
TLS session ticket lifetime hint: 100800 (seconds)
-
TLS session ticket:
-
0000 - 3d e6 41 7f 62 28 49 ae-41 d8 19 29 21 07 80 fe =.A.b(I.A..)!...
-
0010 - 40 b0 ea 1b 2c e7 96 64-e9 0b c5 b3 4d 40 94 01 @...,..d....M@..
-
0020 - 0a 09 71 af 24 f1 d1 55-fb c2 ac ea 8d 38 ee 6e ..q.$..U.....8.n
-
0030 - 62 5f cd fe 07 38 56 31-69 48 cd 73 78 7b 4f d3 b_...8V1iH.sx{O.
-
0040 - 3b 13 d7 92 8f 86 9b 5e-75 5a 6b 92 70 c5 de f5 ;......^uZk.p...
-
0050 - 89 5d 4b c9 ad a9 ab 10-76 3d c6 a9 1b 20 2d 45 .]K.....v=... -E
-
0060 - aa f9 ed e0 85 f3 25 3a-52 ca 00 f2 49 5e 7c da ......%:R...I^|.
-
0070 - f2 46 e2 e7 29 e1 49 a2-1b 55 48 cb 9d aa f1 95 .F..).I..UH.....
-
0080 - ff de fa e2 c1 e5 3e a0-fc 6d 7a 69 6b 51 0f ef ......>..mzikQ..
-
0090 - 00 77 98 13 dc a2 cd 89-0e b6 d8 20 7e cb 06 0b .w......... ~...
-
00a0 - 52 95 00 e3 R...
-
-
Start Time: 1434079554
-
Timeout : 300 (sec)
-
Verify return code: 0 (ok)
-
---
从结果
-
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
-
verify return:1
-
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
-
verify return:1
-
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
-
verify return:1
-
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
-
verify return:1
可以看到,验证是将服务器的证书一层层的验证的,
阅读(5724) | 评论(0) | 转发(0) |