jerry_agle

导航

openSSL入门学习

近来开始学习openssl,写个入门总结。网络已有大量对其介绍,故此不做详述。

下载地址: http://www.openssl.org/source/

解压之后,根目录有install.w32和install.w64两个编译安装文件,

本人工作机子是windows7 64位,但是工作环境是VS2008 32位,因此按install.w32的导读内容进行编译

主要命令如下:

> perl Configure VC-WIN32 no-asm --prefix=D:/openssl/
> ms\do_ms

> nmake -f ms\ntdll.mak

  1. 如果提示nmake命令无法识别,则把%VSInstallPath%/VC/bin添加到系统的path,重启电脑. 重复上面的步骤.

  2. 如果这一步出现编译错误,vs编译cl.exe进程提示dll丢失之类,先把%VSInstallPath%/IDE/目录下的相关dll拷贝到%VSInstallPath%/VC/bin目录下

  3. 如果提示找不到windows.h, 则用dos命令行运行%VSInstallPath%/Common7/Tools下的vsvar32.bat

然后再重新执行nmake -f ms\ntdll.mak命令.

之后进行编译,稍微编译完成之后,进行测试和安装

 > nmake -f ms\ntdll.mak test

 > nmake -f ms\ntdll.mak install

安装的路径既是第一条perl命令制定的路径,这里是: D:/openssl/

安装完成之后,该目录下就有include和lib, bin目录,则外面程序可以使用openssl的api了..

 

 

个人使用openssl进行测试的windows console示例代码:

#include <WinSock2.h>

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>

//注意头文件顺序,因openssl头文件存在着互藕的情况,如果出现编译错误定位于这些头文件,则包含顺序极可能是错误来源

int _tmain(int argc, _TCHAR* argv[])
{
  WSADATA data;
  WSAStartup(MAKEWORD(1, 1), &data);

  char* address = "74.125.235.130";  // google 的一个https地址
  int port = 443;

  SOCKET sockfd = INVALID_SOCKET;
  SOCKADDR_IN server_addr;
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(port);
  server_addr.sin_addr.S_un.S_addr = inet_addr(address);

  int ret = SOCKET_ERROR;
  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
  {
    ret = connect(sockfd, (sockaddr*)&server_addr, sizeof(SOCKADDR_IN));
  }
  if (ret == SOCKET_ERROR)
  {
    return 1;
  }

  // ssl api
  SSL_library_init();

  SSL_CTX* ctx= NULL;
  SSL* ssl = NULL;

  ret = 0;

  ctx = SSL_CTX_new(SSLv23_client_method());
  if (ctx != NULL)
  {
    ssl = SSL_new(ctx);
    if (ssl != NULL)
    {
      ret = SSL_set_fd(ssl, sockfd);
    }
  }
  if (ret <= 0)
  {
    return 1;
  }

  RAND_poll();
  while (RAND_status() == 0)
  {
    unsigned short rand_ret = rand() % 65536;
    RAND_seed(&rand_ret, sizeof(rand_ret));
  }

  ret = SSL_connect(ssl);
  if (ret <= 0)
  {
    printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
    return 1;
  }

  CString cmd;
  cmd.Format(
    "GET /GoogleInternetAuthority/GoogleInternetAuthority.crl HTTP/1.1\r\n"
    "Accept */*\r\n"
    "User-Agent: Microsoft-crytoAPI/6.1\r\n"
    "Host: www.gstatic.com\r\n\r\n"
  );

  int nbytes = SSL_write(ssl, cmd, cmd.GetLength());

  char buf[1024] = {0};

  while(TRUE)
  {
    ret = SSL_read(ssl, buf, 1024);
    switch(SSL_get_error(ssl, ret))
    {
      case SSL_ERROR_NONE:
        nbytes = ret;
        break;
      case SSL_ERROR_ZERO_RETURN:
      case SSL_ERROR_SYSCALL:
      default:
        goto shutdown;
    }

    fwrite(buf, 1, nbytes, stdout);
  }

shutdown:
  ret = SSL_shutdown(ssl);
// if (ret != 1)
// {
// return 1;
// }

  closesocket(sockfd);
  SSL_free(ssl);
  SSL_CTX_free(ctx);

  WSACleanup();

  return 0;
}

posted on 2013-01-23 10:51  子蓝  阅读(958)  评论(0)    收藏  举报