使用C ++在Windows上获取ssl证书 [英] Obtaining ssl certificate on windows using C++

查看:938
本文介绍了使用C ++在Windows上获取ssl证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows上尝试获取远程服务器的SSL证书。我发现一个选项是使用openssl。如互联网上的某些帖子所示,执行此操作的命令为: / p>

I am trying to obtain a remote server's ssl certificate on windows. One option I have found is to use openssl. The command to do that as indicated by some posts on the internet is:

openssl.exe s_client -showcerts -connect {REMOTE_SERVER_IP}:{REMOTE_SERVER_PORT}

这完美地工作,但我的问题是上面的命令有一个300秒的超时。证书本身打印得很快,我看到没有理由等待300秒,当我得到我想要的所有在前几秒钟。仍然我认为没有办法改变s_client上的超时参数。所以我试图找到一种方法来杀死一个过程在Windows后一段给定的时间,但再次没有运气。任何想法如何可以做到这一点?如果有其他窗口方式获取远程服务器ssl证书并将其存储在一个文件中,这也将执行此操作。

This works perfectly, but my problem is that the above command has a timeout of 300 seconds. The certificate itself gets printed pretty fast and I see no reason to wait 300 seconds when I get all I want in the first few seconds. Still I think there is no way to change the timeout parameter on s_client. So I tried to figure a way to kill a process on windows after a given period of time but again had no luck there. Any ideas on how can this be done? If there is some other windows way to a obtain a remote servers ssl certificate and store it in a file this will also do the job.

编辑:根据Bruno的请求添加更多信息。
我试图创建一个c ++应用程序,获取远程服务器的SSL证书并将其存储在文件中以供进一步处理。由于我的应用程序已经使用openssl.exe我需要一个解决方案,使用openssl.exe或标准的Windows命令(即不需要任何额外的库)。

as per Bruno's request adding more information. I am trying to create a c++ application that gets the SSL certificate of a remote server and stores it in a file for further processing. As my application already makes use of openssl.exe I either need a solution that uses openssl.exe or a standard windows command(i.e. does not require any additional libraries).

EDIT2:我已经找到一种方法来避免在linux中等待 - 只是创建一个空文件,并将openssl s_client的输入重定向到它(或使用管道传递空输入)。这在Windows上也是如此,但使用旧版本的openssl(0.9.8l)。我试过它与0.9.8r和与1.0.1b和重定向输入到一个空文件不帮助那里。

I have found a way to avoid the waiting in linux - just create an empty file and redirect the input of openssl s_client to it(or use pipe to pass empty input). This works on windows as well but with older versions of openssl(0.9.8l). I tried it with 0.9.8r and with 1.0.1b and redirecting the input to an empty file does not help there.

推荐答案

这是一个我创建的连接到服务器并将其SSL证书打印到标准输出的简约程序。希望它会帮助别人解决类似的问题:

Here is a minimalistic program I created that connects to a server and prints its ssl certificate to the standard output. Hope it will help someone else to resolve similar issue:

#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#endif

#include <openssl/ssl.h>    
#include <cstdlib>
#include <iostream>

static const char *host= "10.23.10.12";
static int port=443;

int tcp_connect(const char *host,int port)
{
#ifdef WIN32
   WSADATA wsaData;
   WORD version;
   int error;

   version = MAKEWORD( 2, 0 );

   error = WSAStartup( version, &wsaData );

   /* check for error */
   if ( error != 0 )
   {
       /* error occured */
       return -1;
   }

   /* check for correct version */
   if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 0 )
   {
       /* incorrect WinSock version */
       WSACleanup();
       return -1;
   }

   /* WinSock has been initialized */
#endif

   struct hostent *hp;
   struct sockaddr_in addr;
   int sock;

   if(!(hp=gethostbyname(host)))
      printf("Couldn't resolve host");
   memset(&addr,0,sizeof(addr));
   addr.sin_addr=*(struct in_addr*)
         hp->h_addr_list[0];
   addr.sin_family=AF_INET;
   addr.sin_port=htons(port);

   if((sock=(int)socket(AF_INET,SOCK_STREAM,
                   IPPROTO_TCP))<0)
      printf("Couldn't create socket");
   if(connect(sock,(struct sockaddr *)&addr,
              sizeof(addr))<0)
      printf("Couldn't connect socket");

   return sock;
}

int main(int argc,char **argv)
{
   SSL_CTX *ctx;
   SSL *ssl;
   BIO *sbio;
   int sock;

   SSL_METHOD *meth=NULL;
   meth=SSLv23_client_method();
   OpenSSL_add_ssl_algorithms();
   SSL_load_error_strings();
   ctx=SSL_CTX_new(meth);

   /* Connect the TCP socket*/
   sock=tcp_connect(host,port);

   /* Connect the SSL socket */
   ssl=SSL_new(ctx);
   sbio=BIO_new_socket(sock,BIO_NOCLOSE);
   SSL_set_bio(ssl,sbio,sbio);

   if(SSL_connect(ssl)<=0)
     printf("SSL connect error");

   X509 *peer;
   peer=SSL_get_peer_certificate(ssl);
   PEM_write_X509(stdout, peer);

   SSL_CTX_free(ctx);

   close(sock);
#ifdef WIN32
   closesocket(sock);
   WSACleanup();
#else
   close(sock);
#endif
   exit(0);
}

代码是发现的示例的修改版本在这里此帖

The code is modified version of the examples found here as suggested by this post.

编辑:我在Windows上一直收到错误OPENSSL_UPLINK:no OPENSSL_APPLINK。在互联网上进行了大量搜索后,我发现此帖,并将其添加到我的代码: / p>

I kept getting the error OPENSSL_UPLINK: no OPENSSL_APPLINK on windows. After a lot of searching around the internet I found this post and added this to my code:

extern "C" {
   #include <openssl/applink.c>
}

似乎这是一些工作,以避免编译器和运行时选项兼容性。

Seems this is some work around to avoid the requirement for compiler and run-time options compatibility.

这篇关于使用C ++在Windows上获取ssl证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆