码迷,mamicode.com
首页 > 其他好文 > 详细

openssl使用+Demo

时间:2015-01-23 19:42:20      阅读:3312      评论:0      收藏:0      [点我收藏+]

标签:

1. website
SSL(secure Socket Layer)
TLS(transport Layer Security) - SSL3.0基础之上提出的安全通信标准,目前版本是1.0
openssl 主页 -> http://www.openssl.org/
openssl 中文文档 -> http://www.chinaunix.net/jh/13/478901.html

2. 如何编译OpenSSL in Windows?
a) 下载openssl -> openssl-0.9.8i
b) 下载perl -> http://downloads.activestate.com/ActivePerl/Windows/5.8/ActivePerl-5.8.8.822-MSWin32-x86-280952.zip
c) 安装perl -> ActivePerl-5.8.8.822-MSWin32-x86-280952/Installer.bat (之前先运行vcvars32.bat,需要运行perf Configure VC-WIN32来设置环境变量)
d) 使windows支持nmake -> C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat
e) 进入openssl路径 -> cd C:\devdiv\openssl-0.9.8i    (工作路径)
f) 创建Makefile文件: ms\do_ms     (出现%osversion% is not defined的错误忽略即可)
g) 编译动态库: nmake -f ms\ntdll.mak
   编译静态库: nmake -f ms\nt.mak

   测试动态库: nmake -f ms\ntdll.mak test
   测试静态库: nmake -f ms\nt.mak test

   安装动态库: nmake -f ms\ntdll.mak install
   安装静态库: nmake -f ms\nt.mak install

   清除上次动态库的编译,以便重新编译: nmake -f ms\ntdll.mak clean
   清除上次静态库的编译,以便重新编译: nmake -f ms\nt.mak clean
   
3. 如何使用openssl?
a) library path -> C:\devdiv\openssl-0.9.8i\out32
b) include path -> C:\devdiv\openssl-0.9.8i\include
c) 库文件 -> libeay32.lib, ssleay32.lib

4. 配置文件在哪里?
C:\devdiv\openssl-0.9.8i\apps\openssl.cnf

5. 关于key:
key一般分为public key和private key,在openssl中,private key中包含了public key的信息,所以public key不需要单独创建. 如何创建一个RSA key?
openssl.exe genrsa -des3 -out privatekey.pem 2048  (需要添加密码保护)
openssl.exe genrsa -out privatekey.pem 2048

6. 关于certificates(证书文件), 如何创建一个证书呢?
一般流程是:
a. 创建一个private key
b. 创建一个certificate signing request(证书请求), 这个需要a#中创建的private key.因为证书中需要包含public key,
创建的priavate key中有这些信息.
(openssl.exe req -new -key privatekey.pem-out cacert.csr)
c. 把创建好的证书请求拿到CA(certificate authority)证书认证机构审批.

7. 如何做一个自签名的证书呢?
openssl.exe req -new -x509 -key privatekey.pem -out cacert.pem -days 1095
(Note: privatekey.pem需要自己创建)

8. Demo: 来自openssl自带的demo,略做修改.
Server:

  1技术分享#include <openssl/rsa.h>       /* SSLeay stuff */
  2技术分享#include <openssl/crypto.h>
  3技术分享#include <openssl/x509.h>
  4技术分享#include <openssl/pem.h>
  5技术分享#include <openssl/ssl.h>
  6技术分享#include <openssl/err.h>
  7技术分享
  8技术分享
  9技术分享#include <iostream>
 10技术分享#include <winsock2.h>
 11技术分享
 12技术分享#define SERVER_PORT    5003
 13技术分享
 14技术分享// certificate & key 的存放路径
 15技术分享// Note: 必须是全路径, 否则SSL_CTX_use_certificate_file等函数
 16技术分享//       无法找到文件在windows平台上.
 17技术分享// How to:
 18技术分享// #privatekey.pem
 19技术分享// openssl.exe genrsa -out privatekey.pem 2048
 20技术分享// #cacert.pem
 21技术分享// openssl.exe req -new -x509 -key privatekey.pem -out cacert.pem -days 1095 -config openssl.cnf
 22技术分享//
 23技术分享#define SERVER_CERTIFICATE   "c:\\config\\cacert.pem"    
 24技术分享#define SERVER_KEY           "c:\\config\\privatekey.pem"
 25技术分享
 26技术分享#pragma comment( lib, "ws2_32.lib" )
 27技术分享#pragma comment( lib, "libeay32.lib" )
 28技术分享#pragma comment( lib, "ssleay32.lib" )
 29技术分享
 30技术分享int main( int argc, char* argv[] ) {
 31技术分享  int ret;
 32技术分享
 33技术分享  ////////////
 34技术分享  // 初始化 //
 35技术分享  ////////////
 36技术分享  SSL_CTX* ctx;
 37技术分享  SSL_METHOD *meth;
 38技术分享
 39技术分享  SSL_load_error_strings();
 40技术分享  SSLeay_add_ssl_algorithms();
 41技术分享  meth = SSLv23_server_method(); 
 42技术分享
 43技术分享  ctx = SSL_CTX_new (meth);
 44技术分享  if (!ctx) {
 45技术分享    ERR_print_errors_fp(stderr);
 46技术分享    std::cout<<"SSL_CTX_new error."<<std::endl;
 47技术分享    return -1;
 48技术分享  }
 49技术分享  
 50技术分享  if (SSL_CTX_use_certificate_file(ctx, SERVER_CERTIFICATE, SSL_FILETYPE_PEM) <= 0) {
 51技术分享    ERR_print_errors_fp(stderr);
 52技术分享    std::cout<<"SSL_CTX_use_certificate_file error."<<std::endl;
 53技术分享    return -1;
 54技术分享  }
 55技术分享  if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0) {
 56技术分享    ERR_print_errors_fp(stderr);
 57技术分享    std::cout<<"SSL_CTX_use_PrivateKey_file error."<<std::endl;
 58技术分享    return -1;
 59技术分享  }
 60技术分享
 61技术分享  if (!SSL_CTX_check_private_key(ctx)) {
 62技术分享    ERR_print_errors_fp(stderr);
 63技术分享    std::cout<<"SSL_CTX_check_private_key error."<<std::endl;
 64技术分享    return -1;
 65技术分享  }
 66技术分享
 67技术分享  ///////////////////////
 68技术分享  // 建立原始的TCP连接 //
 69技术分享  ///////////////////////
 70技术分享  WSADATA wsaData;
 71技术分享  SOCKET listen_socket;
 72技术分享  SOCKET accept_socket;
 73技术分享  struct sockaddr_in addr_server;
 74技术分享  struct sockaddr_in addr_client;
 75技术分享  int addr_client_len;
 76技术分享
 77技术分享  ret = WSAStartup( MAKEWORD(2, 2), &wsaData );
 78技术分享  if ( ret != 0 ) {
 79技术分享    std::cout<<"WSAStartup error."<<std::endl;
 80技术分享    return -1;
 81技术分享  }
 82技术分享
 83技术分享  listen_socket = socket (AF_INET, SOCK_STREAM, 0);  
 84技术分享  if( listen_socket == INVALID_SOCKET  ) {
 85技术分享    std::cout<<"socket error."<<std::endl;
 86技术分享    return -1;
 87技术分享  }
 88技术分享  
 89技术分享  memset (&addr_server, 0, sizeof(addr_server));
 90技术分享  addr_server.sin_family           = AF_INET;
 91技术分享  addr_server.sin_addr.S_un.S_addr = INADDR_ANY;
 92技术分享  addr_server.sin_port             = htons (SERVER_PORT);        
 93技术分享  
 94技术分享  ret = bind(listen_socket, (struct sockaddr*)&addr_server, sizeof(addr_server) ); 
 95技术分享  if( ret == SOCKET_ERROR )  {
 96技术分享     std::cout<<"bind error."<<std::endl;
 97技术分享     return -1;
 98技术分享  }
 99技术分享         
100技术分享  ret = listen (listen_socket, 5); 
101技术分享  if( ret == SOCKET_ERROR ) {
102技术分享    std::cout<<"listen error."<<std::endl;
103技术分享    return -1;
104技术分享  }
105技术分享  
106技术分享  addr_client_len = sizeof(addr_client);
107技术分享  accept_socket = accept (listen_socket, (struct sockaddr*) &addr_client, &addr_client_len);
108技术分享  if( accept_socket == INVALID_SOCKET  ) {
109技术分享    std::cout<<"accept error."<<std::endl;
110技术分享    return -1;
111技术分享  }
112技术分享  closesocket(listen_socket);
113技术分享  std::cout<<" Connection from "<<addr_client.sin_addr.S_un.S_addr<<":"<<addr_client.sin_port<<std::endl;
114技术分享
115技术分享  /////////////////////////////////////
116技术分享  // TCP连接已经建立,执行Server SSL //
117技术分享  /////////////////////////////////////
118技术分享  SSL*     ssl;
119技术分享  X509*    client_certificate;
120技术分享  char*    str;
121技术分享
122技术分享  ssl = SSL_new (ctx);                           
123技术分享  if( ssl == NULL ) {
124技术分享    std::cout<<"SSL_new error."<<std::endl;
125技术分享    return -1;
126技术分享  } 
127技术分享  SSL_set_fd (ssl, accept_socket);
128技术分享  ret = SSL_accept (ssl);                     
129技术分享  if( ret == -1 ) {
130技术分享    std::cout<<"SSL_accept error."<<std::endl;
131技术分享    return -1;
132技术分享  }
133技术分享  
134技术分享  // 获取cipher
135技术分享  std::cout<<"SSL connection using: "<<SSL_get_cipher(ssl)<<std::endl;
136技术分享  
137技术分享  // 获取客户端的证书
138技术分享  client_certificate = SSL_get_peer_certificate (ssl);
139技术分享  if (client_certificate != NULL) {
140技术分享    std::cout<<"Client certificate:"<<std::endl;
141技术分享    
142技术分享    str = X509_NAME_oneline (X509_get_subject_name (client_certificate), 0, 0);
143技术分享    if( str == NULL ) {
144技术分享      std::cout<<"X509_NAME_oneline error."<<std::endl;
145技术分享    } else {
146技术分享      std::cout<<"subject: "<<str<<std::endl;
147技术分享      OPENSSL_free (str);
148技术分享    }
149技术分享    
150技术分享    str = X509_NAME_oneline (X509_get_issuer_name  (client_certificate), 0, 0);
151技术分享    if( str == NULL ) {
152技术分享      std::cout<<"X509_NAME_oneline error."<<std::endl;
153技术分享    } else {
154技术分享      std::cout<<"issuer: "<<str<<std::endl;
155技术分享      OPENSSL_free (str);
156技术分享    }
157技术分享
158技术分享    X509_free (client_certificate);
159技术分享  } else {
160技术分享    std::cout<<"Client does not have certificate. "<<std::endl;
161技术分享  }
162技术分享
163技术分享  ////////////////
164技术分享  //  数据交换  //
165技术分享  ////////////////
166技术分享  char     buf [4096];
167技术分享
168技术分享  ret = SSL_read (ssl, buf, sizeof(buf) - 1);    
169技术分享  if( ret == -1 ) {
170技术分享    std::cout<<"SSL_read error."<<std::endl;
171技术分享    return -1;
172技术分享  }
173技术分享  buf[ret] = ‘\0‘;
174技术分享  std::cout<<buf<<std::endl;
175技术分享  
176技术分享  ret = SSL_write (ssl, "I hear you.", strlen("I hear you.")); 
177技术分享  if( ret == -1 ) {
178技术分享    std::cout<<"SSL_write error."<<std::endl;
179技术分享    return -1;
180技术分享  }
181技术分享
182技术分享  /////////////
183技术分享  // Cleanup //
184技术分享  /////////////
185技术分享  closesocket(accept_socket);
186技术分享  SSL_free (ssl);
187技术分享  SSL_CTX_free (ctx);
188技术分享  WSACleanup();
189技术分享  return 0;
190技术分享}

Client:

  1技术分享#include <openssl/rsa.h>       /* SSLeay stuff */
  2技术分享#include <openssl/crypto.h>
  3技术分享#include <openssl/x509.h>
  4技术分享#include <openssl/pem.h>
  5技术分享#include <openssl/ssl.h>
  6技术分享#include <openssl/err.h>
  7技术分享
  8技术分享
  9技术分享#include <iostream>
 10技术分享#include <winsock2.h>
 11技术分享
 12技术分享#define SERVER_IP      "127.0.0.1"
 13技术分享#define SERVER_PORT    5003
 14技术分享
 15技术分享#pragma comment( lib, "ws2_32.lib" )
 16技术分享#pragma comment( lib, "libeay32.lib" )
 17技术分享#pragma comment( lib, "ssleay32.lib" )
 18技术分享
 19技术分享
 20技术分享int main( int argc, char* argv[] ) {
 21技术分享  int ret;
 22技术分享  ////////////
 23技术分享  // 初始化 //
 24技术分享  ////////////
 25技术分享  SSL_CTX* ctx;
 26技术分享  SSL_METHOD *meth;
 27技术分享
 28技术分享  SSL_load_error_strings();
 29技术分享  SSLeay_add_ssl_algorithms();
 30技术分享  meth = SSLv23_client_method();
 31技术分享
 32技术分享  ctx = SSL_CTX_new (meth);
 33技术分享  if (!ctx) {
 34技术分享    ERR_print_errors_fp(stderr);
 35技术分享    std::cout<<"SSL_CTX_new error."<<std::endl;
 36技术分享    return -1;
 37技术分享  }
 38技术分享
 39技术分享  ///////////////////////
 40技术分享  // 建立原始的TCP连接 //
 41技术分享  ///////////////////////
 42技术分享  WSADATA wsaData;
 43技术分享  SOCKET client_socket;
 44技术分享  struct sockaddr_in addr_server;
 45技术分享
 46技术分享  ret = WSAStartup( MAKEWORD(2, 2), &wsaData );
 47技术分享  if ( ret != 0 ) {
 48技术分享    std::cout<<"WSAStartup error."<<std::endl;
 49技术分享    return -1;
 50技术分享  }
 51技术分享  client_socket = socket (AF_INET, SOCK_STREAM, 0);  
 52技术分享  if( client_socket == INVALID_SOCKET  ) {
 53技术分享    std::cout<<"socket error."<<std::endl;
 54技术分享    return -1;
 55技术分享  }
 56技术分享  
 57技术分享  memset (&addr_server, 0, sizeof(addr_server));
 58技术分享  addr_server.sin_family           = AF_INET;
 59技术分享  addr_server.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
 60技术分享  addr_server.sin_port             = htons (SERVER_PORT);
 61技术分享
 62技术分享  ret = connect(client_socket, (struct sockaddr*) &addr_server, sizeof(addr_server)); 
 63技术分享  if( client_socket == SOCKET_ERROR  ) {
 64技术分享    std::cout<<"connect error."<<std::endl;
 65技术分享    return -1;
 66技术分享  }
 67技术分享
 68技术分享  /////////////////////////////////////
 69技术分享  // TCP连接已经建立,执行Client SSL //
 70技术分享  /////////////////////////////////////
 71技术分享  SSL*     ssl;
 72技术分享  X509*    server_certificate;
 73技术分享  char*    str;
 74技术分享
 75技术分享  ssl = SSL_new (ctx);                         
 76技术分享  if( ssl == NULL ) {
 77技术分享    std::cout<<"SSL_new error."<<std::endl;
 78技术分享    return -1;
 79技术分享  } 
 80技术分享  SSL_set_fd (ssl, client_socket);
 81技术分享  ret = SSL_connect (ssl);                     
 82技术分享  if( ret == -1 ) {
 83技术分享    std::cout<<"SSL_accept error."<<std::endl;
 84技术分享    return -1;
 85技术分享  }
 86技术分享    
 87技术分享  // 接下来的获取密码和获取服务器端证书的两部是可选的,不会影响数据交换
 88技术分享  
 89技术分享  // 获取cipher
 90技术分享  std::cout<<"SSL connection using: "<<SSL_get_cipher(ssl)<<std::endl;
 91技术分享  
 92技术分享  // 获取服务器端的证书
 93技术分享  server_certificate = SSL_get_peer_certificate (ssl);       
 94技术分享  if( server_certificate != NULL ) {
 95技术分享    std::cout<<"Server certificate:"<<std::endl;
 96技术分享
 97技术分享    str = X509_NAME_oneline (X509_get_subject_name (server_certificate),0,0);
 98技术分享    if( str == NULL ) {
 99技术分享      std::cout<<"X509_NAME_oneline error."<<std::endl;
100技术分享    } else {
101技术分享      std::cout<<"subject: "<<str<<std::endl;
102技术分享      OPENSSL_free (str);
103技术分享    }
104技术分享
105技术分享    str = X509_NAME_oneline (X509_get_issuer_name  (server_certificate),0,0);
106技术分享    if( str == NULL ) {
107技术分享      std::cout<<"X509_NAME_oneline error."<<std::endl;
108技术分享    } else {
109技术分享      std::cout<<"issuer: "<<str<<std::endl;
110技术分享      OPENSSL_free (str);
111技术分享    }
112技术分享
113技术分享    X509_free (server_certificate);
114技术分享  } else {
115技术分享    std::cout<<"Server does not have certificate. we sould Esc!"<<std::endl;
116技术分享    return -1;
117技术分享  }
118技术分享
119技术分享  ////////////////
120技术分享  //  数据交换  //
121技术分享  ////////////////
122技术分享  char     buf [4096];
123技术分享
124技术分享  ret = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  
125技术分享  if( ret == -1 ) {
126技术分享    std::cout<<"SSL_write error."<<std::endl;
127技术分享    return -1;
128技术分享  }
129技术分享  ret = SSL_read (ssl, buf, sizeof(buf) - 1);  
130技术分享  if( ret == -1 ) {
131技术分享    std::cout<<"SSL_read error."<<std::endl;
132技术分享    return -1;
133技术分享  }
134技术分享  buf[ret] = ‘\0‘;
135技术分享  std::cout<<buf<<std::endl;
136技术分享  SSL_shutdown(ssl);  /* send SSL/TLS close_notify */
137技术分享  
138技术分享  /////////////
139技术分享  // Cleanup //
140技术分享  /////////////
141技术分享  closesocket(client_socket);
142技术分享  SSL_free (ssl);
143技术分享  SSL_CTX_free (ctx);
144技术分享  WSACleanup();
145技术分享  return 0;
146技术分享}

最后的输出结果:
Server-Console:
Connection from 16777343:20314
SSL connection using: AES256-SHA
Client does not have certificate.
Hello World!


Client-Console:
SSL connection using: AES256-SHA
Server certificate:
subject: /C=cn/ST=shanghai/L=shanghai/O=shanghai/OU=shanghai/CN=shanghai/emailAd
dress=ysong.lee@gmail.com
issuer: /C=cn/ST=shanghai/L=shanghai/O=shanghai/OU=shanghai/CN=shanghai/emailAdd
ress=ysong.lee@gmail.com
I hear you.

openssl使用+Demo

标签:

原文地址:http://www.cnblogs.com/xunbu7/p/4244881.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!