openssl证书生成和源码wince编译及其使用

来源:互联网 发布:国外高匿代理ip和端口 编辑:程序博客网 时间:2024/05/21 15:06

OpenSSL

一、证书

1、  证书制作

1)  生成root 证书

 <server>

openssl genrsa -out server\server_root.key 2048

              openssl  req -x509 -new -key server\server_root.key-days 10000 -out server\server_root.crt -subj"/C=US/ST=California/L=SiliconValley/O=CAcert.org/OU=CAcert/CN=server_root/emailAddress=sample@cacert.org"

输出:server\server_root.key server\server_root.crt

<client>

openssl genrsa -out client\client_root.key 2048

openssl req -x509 -new -key client\client_root.key -days 10000 -outclient\client_root.crt -subj "/C=US/ST=California/L=SiliconValley/O=CAcert.org/OU=CAcert/CN=client_root/emailAddress=sample@cacert.org"

输出:client\client_root.key client\client_root.crt

2)  生成CA证书

<server>

openssl genrsa -out server\ford_server.key 2048

openssl req -new -key server\ford_server.key -days 10000 -outserver\ford_server.crt.req -subj"/C=US/ST=Michigan/L=Detroit/O=FORD_SERVER/OU=FORD_SDL_SERVER/CN=FORD/emailAddress=sample@ford.com"

openssl x509 -hash -req -in server\ford_server.crt.req -CAserver\server_root.crt -CAkey server\server_root.key -CAcreateserial -outserver\ford_server.crt -days 10000

输出:server\ford_server.key server\ford_server.crt

<client>

openssl genrsa -out client\ford_client.key 2048

openssl req -new -key client\ford_client.key -days 10000 -outclient\ford_client.crt.req -subj"/C=US/ST=Michigan/L=Detroit/O=FORD_CLIENT/OU=FORD_SDL_CLIENT/CN=FORD_CLIENT/emailAddress=sample@ford.com"

openssl x509 -hash -req -in client\ford_client.crt.req -CAclient\client_root.crt -CAkey client\client_root.key -CAcreateserial -outclient\ford_client.crt -days 10000

输出:client\ford_client.key  client\ford_client.crt

3)  分别合并

输出:server\ server_verification_ca_cetrificates.crt client\ client_verification_ca_cetrificates.crt

 

4)  生成签名加密证书

<server>

openssl genrsa -out server\server.key 2048

openssl req -new -key server\server.key -days 10000 -out server\server.crt.req-subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=Mobile/CN=server/emailAddress=sample@luxoft.com/serialNumber=SPT"

openssl x509 -hash -req -in server\server.crt.req -CA server\ford_server.crt-CAkey server\ford_server.key -CAcreateserial -out server\server.crt -days10000

openssl pkcs12 -export -out server\spt_credential.p12 -inkey server\server.key-in server\server.crt -name "SPT key and certificates" -CAfile client\client_verification_ca_cetrificates.crt  -passout pass:

输出:server\server.key server\server.crt  server\spt_credential.p12

<client>

openssl genrsa -out client\client.key 2048

openssl req -new -key client\client.key -days 10000 -out client\client.crt.req-subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=HeadUnit/CN=client/emailAddress=sample@luxoft.com/serialNumber=SPT"

openssl x509 -hash -req -in client\client.crt.req -CA client\ford_client.crt-CAkey client\ford_client.key -CAcreateserial -out client\client.crt -days10000

输出:client\client.key client\client.crt

5)  生成无签名证书

<server>

openssl req -x509 -new -key server\server.key -days 10000 -outserver\server_unsigned.crt -subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=Mobile_unsigned/CN=server/emailAddress=sample@luxoft.com/serialNumber=SPT"

openssl pkcs12 -export -out server\spt_credential_unsigned.p12 -inkeyserver\server.key -in server\server_unsigned.crt -name "SPT key andcertificates" -CAfile  client\client_verification_ca_cetrificates.crt  -passout pass:

openssl req -new -key server\server.key -days 10000 -outserver\server_expired.crt.req -subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=Mobile_expired/CN=server/emailAddress=sample@luxoft.com/serialNumber=SPT"

输出:server\server_unsigned.crt  server\spt_credential_unsigned.p12  server\server_expired.crt.req server\spt_credential_unsigned.p12.enc (base64编码)

<client>

openssl req -x509 -new -key client\client.key -days 10000 -out client\client_unsigned.crt-subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=Mobile_unsigned/CN=client/emailAddress=sample@luxoft.com/serialNumber=SPT"

openssl pkcs12 -export -out client\client_credential_unsigned.p12 -inkeyclient\client.key -in client\client_unsigned.crt -name "SPT key andcertificates" -CAfile server\server_verification_ca_cetrificates.crt  -passout pass:

1> --== Client pkcs12 expiredcertificate generating ==--

openssl req -new -key client\client.key -days 10000 -out client\client_expired.crt.req-subj "/C=RU/ST=Russia/L=St.Petersburg/O=Luxoft/OU=Mobile_expired/CN=client/emailAddress=sample@luxoft.com/serialNumber=SPT"

输出:client\client_unsigned.crt client\client_credential_unsigned.p12 client\client_expired.crt.req client\client_credential_unsigned.p12.enc(base64编码)

 

二、编译

1) 下载openssl  :git clone https://github.com/openssl/openssl.git

2)  下载并编译wcecompat,wince openssl依赖它的头文件和库

地址:git clone https://github.com/mauricek/wcecompat.git

编译wcecompat ,直接使用Qt打开wcecompat.pro用Qt编译即可完成

然后把编译好的.lib 文件和include 文件夹放到c盘c:\wcecompat

3)  下载并安装Microsoft eMbedded C++ 4.0

4)  安装WCE SDK,例如CHSINT SDK For WinCE(ARMV4I)

5)  下载并安装perl

6)  编译openssl:

a)  找到C:\Program Files (x86)\Microsoft eMbedded C++ 4.0\EVC\WCE400\BIN\WCEARMV4I.BAT用文本编辑器打开,修改以下内容:

REM   PLATFORM=CHSINT SDK For WinCE 6.0

REM        OSVERSION=WCE600

REM        WCEROOT=C:\Program Files(x86)\Microsoft eMbedded C++ 4.0 

REM        SDKROOT=C:\Program Files (x86)\WindowsCE Tools

 

setPATH=%WCEROOT%\COMMON\EVC\bin;%WCEROOT%\EVC\WCE400\bin;C:\Program Files(x86)\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm;C:\Program Files(x86)\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files (x86)\MicrosoftVisual Studio 9.0\Common7\Tools;C:\Program Files (x86)\Microsoft Visual Studio9.0\Common7\IDE;%path%

setINCLUDE=%SDKROOT%\%OSVERSION%\%PLATFORM%\include\ARMV4I;%SDKROOT%\%OSVERSION%\%PLATFORM%\MFC\include;%SDKROOT%\%OSVERSION%\%PLATFORM%\ATL\include;C:\ProgramFiles (x86)\Microsoft Visual Studio 9.0\VC\ce\include;C:\Program Files(x86)\Microsoft Visual Studio 9.0\VC\ce\atlmfc\include;

set LIB=%SDKROOT%\%OSVERSION%\%PLATFORM%\lib\ARMV4I;%SDKROOT%\%OSVERSION%\%PLATFORM%\MFC\lib\ARMV4I;%SDKROOT%\%OSVERSION%\%PLATFORM%\ATL\lib\ARMV4I;C:\ProgramFiles (x86)\Microsoft Visual Studio 9.0\VC\ce\lib\armv4i;C:\Program Files(x86)\Microsoft Visual Studio 9.0\VC\ce\atlmfc\lib\armv4i;

 

b)  运行cmd,执行刚才修改的WCEARMV4I.BAT 文件

c)  设置WCECOMPAT的路径,否则openssl找不到相关头文件和依赖的库。执行 set WCECOMPAT=C:\wcecompat

需要注意的是 wcecompat  源码下 time.c 里面涉及struct tm的需要修改,这是个bug,

struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};


tm_year 的值=实际年份-1900

tm_mon=实际月份-1

比如2016年8月20日,那么它的值应该是: 

tm_year=2016-1900=116;

tm_mon=8-1=7

如果不改,可能导致openssl 校验证书时会出现“format error in certificate's notBefore field” 错误,实际上证书没错,只是wcecompat里面gmtime错了,导致openssl里面调用的时候 tm_year=2016 ,不在取值范围内

d)  set OSVERSION=WCE600

e)  cd到openssl源码目录执行perl Configure VC-CE

f)  执行ms\do_ms 生成两个mak文件,ms\ce.mak 和ms\cedll.mak,一个是静态库一个是动态库

g)  删除ms\ce.mak里面的CFLAG 里面的-WX,然后执行nmake –f ms\ce.mak 编译完成。

 

三、使用openssl

1)   初始化

SSL_load_error_strings();

ERR_load_BIO_strings();

OpenSSL_add_all_algorithms();

   SSL_library_init();

2)   建立安全连接

server 端:以1.0版本协议为例

// 设置SSL指针

SSL_CTX *ctx=SSL_CTX_new(SSLv1_server_method());

// 建立连接

SSL *conn = SSL_new(SSL_CTX* ctx);

void SSL_set_accept_state(SSL *);// server端使用

void SSL_set_connect_state(SSL *);// client端使用

3)   证书使用

// base64解码

BIO* bio =BIO_new(BIO_f_base64());

                 BIO* bmem = BIO_new_mem_buf((char*)cert_data.c_str(),cert_data.length());

                  bmem = BIO_push(bio, bmem);

 

                char* buf = new char[cert_data.length()];

                int len =BIO_read(bmem, buf,cert_data.length());

BIO* bio_cert =BIO_new(BIO_s_mem());

                 int k = BIO_write(bio_cert, buf, len);

  PKCS12* p12 = d2i_PKCS12_bio(bio_cert,NULL);

                  EVP_PKEY* pkey =NULL;

                  X509* cert =NULL;

                  PKCS12_parse(p12, NULL, &pkey,&cert, NULL);

SSL_CTX_use_certificate(context_,cert);

asn1_time_to_tm(X509_get_notAfter(cert));

SSL_CTX_use_PrivateKey(context_,pkey);

SSL_CTX_check_private_key(context_);

 

// 加载信任证书

SSL_CTX_load_verify_locations(SSL_CTX *ctx,const char *CAfile,

                                  const char *CApath);

CAfile是可信任证书文件名,CApath证书所在路径

4)   读写操作

// 设置BIO,用于存放读写的缓存

void SSL_set_bio(SSL *s,BIO *rbio, BIO *wbio);

SSL_is_init_finished(a); //在通信之前有个握手操作,握手操作完成才能算初始化完成

int BIO_read(BIO *b,void *data, int len);

int BIO_write(BIO *b,const void *data,int len);

 

5)  握手操作

在通信之前有个握手操作,交换验证证书

//握手操作

int SSL_do_handshake(SSL *s);

6)   结束处理

void  SSL_shutdown(SSL *);

void  free(SSL *);

void SSL_CTX_free(SSL_CTX *);

1 0
原创粉丝点击