OpenSSL编程
简介
OpenSSL是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。
OpenSSL采用C语言作为开发语言,这使得它具有优秀的跨平台性能。OpenSSL支持Linux、UNIX、windows、Mac等平台。OpenSSL目前最新的版本是openssl-1.0.0e.
编译安装
1、资源下载
- http://www.openssl.org/source/openssl-1.0.0e.tar.gz
2、编译安装
- cd openssl-1.0.0e
- ./config
- make
- make install
API文档
- http://www.openssl.org/docs/crypto/crypto.html
- http://www.openssl.org/docs/ssl/ssl.html
编程示例
程序1:openssl堆栈示例
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <openssl/safestack.h>
- #define sk_Student_new(st) SKM_sk_new(Student, (st))
- #define sk_Student_new_null() SKM_sk_new_null(Student)
- #define sk_Student_free(st) SKM_sk_free(Student, (st))
- #define sk_Student_num(st) SKM_sk_num(Student, (st))
- #define sk_Student_value(st, i) SKM_sk_value(Student, (st), (i))
- #define sk_Student_set(st, i, val) SKM_sk_set(Student, (st), (i), (val))
- #define sk_Student_zero(st) SKM_sk_zero(Student, (st))
- #define sk_Student_push(st, val) SKM_sk_push(Student, (st), (val))
- #define sk_Student_unshift(st, val) SKM_sk_unshift(Student, (st), (val))
- #define sk_Student_find(st, val) SKM_sk_find(Student, (st), (val))
- #define sk_Student_delete(st, i) SKM_sk_delete(Student, (st), (i))
- #define sk_Student_delete_ptr(st, ptr) SKM_sk_delete_ptr(Student, (st), (ptr))
- #define sk_Student_insert(st, val, i) SKM_sk_insert(Student, (st), (val), (i))
- #define sk_Student_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(Student, (st), (cmp))
- #define sk_Student_dup(st) SKM_sk_dup(Student, st)
- #define sk_Student_pop_free(st, free_func) SKM_sk_pop_free(Student, (st), (free_func))
- #define sk_Student_shift(st) SKM_sk_shift(Student, (st))
- #define sk_Student_pop(st) SKM_sk_pop(Student, (st))
- #define sk_Student_sort(st) SKM_sk_sort(Student, (st))
- typedef struct Student_st
- {
- char *name;
- int age;
- char *otherInfo;
- } Student;
- typedef STACK_OF(Student) Students;
- Student *Student_Malloc()
- {
- Student *a=malloc(sizeof(Student));
- a->name=(char *)malloc(sizeof(char)*20);
- strcpy(a->name,"zcp");
- a->otherInfo=(char *)malloc(sizeof(char)*20);
- strcpy(a->otherInfo,"no info");
- return a;
- }
- void Student_Free(Student *a)
- {
- free(a->name);
- free(a->otherInfo);
- free(a);
- }
- static int Student_cmp(Student *a,Student *b)
- {
- int ret;
- ret=strcmp(a->name,b->name); /* 只比较关键字 */
- return ret;
- }
- int main()
- {
- Students *s,*snew;
- Student *s1,*one,*s2;
- int i,num;
- s=sk_Student_new_null(); /* 新建一个堆栈对象 */
- snew=sk_Student_new(Student_cmp); /* 新建一个堆栈对象 */
- s2=Student_Malloc();
- sk_Student_push(snew,s2);
- i=sk_Student_find(snew,s2);
- s1=Student_Malloc();
- sk_Student_push(s,s1);
- num=sk_Student_num(s);
- for(i=0; i<num; i++)
- {
- one=sk_Student_value(s,i);
- printf("student name : %s\n",one->name);
- printf("sutdent age : %d\n",one->age);
- printf("student otherinfo : %s\n\n\n",one->otherInfo);
- }
- sk_Student_pop_free(s,Student_Free);
- sk_Student_pop_free(snew,Student_Free);
- return 0;
- }
编译
- gcc example1.c -o example1 -L/usr/lib -lssl -lcrypto
运行
程序2:openssl哈希表示例
- #include <string.h>
- #include <openssl/lhash.h>
- typedef struct Student_st
- {
- char name[20];
- int age;
- char otherInfo[200];
- } Student;
- static int Student_cmp(const void *a, const void *b)
- {
- char *namea=((Student *)a)->name;
- char *nameb=((Student *)b)->name;
- return strcmp(namea,nameb);
- }
- /* 打印每个值*/
- static void PrintValue(Student *a)
- {
- printf("name :%s\n",a->name);
- printf("age :%d\n",a->age);
- printf("otherInfo : %s\n",a->otherInfo);
- }
- static void PrintValue_arg(Student *a,void *b)
- {
- int flag=0;
- flag=*(int *)b;
- printf("用户输入参数为:%d\n",flag);
- printf("name :%s\n",a->name);
- printf("age :%d\n",a->age);
- printf("otherInfo : %s\n",a->otherInfo);
- }
- int main()
- {
- int flag=11;
- _LHASH *h;
- Student s1= {"zcp",28,"hu bei"},
- s2= {"forxy",28,"no info"},
- s3= {"skp",24,"student"},
- s4= {"zhao_zcp",28,"zcp's name"},
- *s5;
- void *data;
- /*创建哈希表*/
- h=lh_new(NULL,Student_cmp);
- if(h==NULL)
- {
- printf("err.\n");
- return -1;
- }
- /*将数据插入哈希表*/
- data=&s1;
- lh_insert(h,data);
- data=&s2;
- lh_insert(h,data);
- data=&s3;
- lh_insert(h,data);
- data=&s4;
- lh_insert(h,data);
- /*遍历打印*/
- lh_doall(h,PrintValue);
- lh_doall_arg(h,PrintValue_arg,(void *)(&flag));
- /*查找数据*/
- data=lh_retrieve(h,(const void*)"skp");
- if(data==NULL)
- {
- printf("can not find skp!\n");
- lh_free(h);
- return -1;
- }
- else
- {
- s5=data;
- printf("\n\nstudent name : %s\n",s5->name);
- printf("sutdent age : %d\n",s5->age);
- printf("student otherinfo : %s\n",s5->otherInfo);
- lh_free(h);
- }
- getchar();
- return 0;
- }
编译
- gcc example2.c -o example2 -L/usr/lib -lssl -lcrypto
运行
程序3:openssl内存管理示例
- #include <openssl/crypto.h>
- #include <openssl/bio.h>
- int main()
- {
- char *p;
- BIO *b;
- CRYPTO_malloc_debug_init();
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); /*开户内存记录*/
- p=OPENSSL_malloc(4);
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);/*关闭内存记录*/
- b=BIO_new_file("leak.log","w");
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
- CRYPTO_mem_leaks(b); /*将内存泄露输出到FILE中*/
- OPENSSL_free(p);
- BIO_free(b);
- return 0;
- }
编译
- gcc example3.c -o example3 -L/usr/lib -lssl -lcrypto
运行
程序4:动态模块加载
- #include <openssl/dso.h>
- #include <openssl/bio.h>
- #include <openssl/safestack.h>
- int main()
- {
- DSO *d;
- void (*f)();
- BIO *(*BIO_newx)(BIO_METHOD *a);
- BIO *test;
- char *load_name;
- const char *loaded_name;
- int flags;
- d=DSO_new();
- #if 0
- DSO_set_name_converter
- DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL);
- DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NAME_TRANSLATION_EXT_ONLY,NULL);
- DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_GLOBAL_SYMBOLS,NULL);
- /* 最好写成libeay32而不是libeay32.dll, 除非前面调用了DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL)否则它会加载libeay32.dll.dll
- */
- load_name=DSO_merge(d,"libeay32","D:\\zcp\\OpenSSL\\openssl-0.9.8b\\out32dll\\Debug");
- #endif
- d=DSO_load(d,"libeay32",NULL,0);
- if(d==NULL)
- {
- printf("err");
- return -1;
- }
- loaded_name=DSO_get_loaded_filename(d);
- if(loaded_name!=NULL)
- {
- printf("loaded file is %s\n",loaded_name);
- }
- flags=DSO_flags(d);
- printf("current falgs is %d\n",flags);
- DSO_up_ref(d);
- f=(void (*)())DSO_bind_var(d,"BIO_new");
- BIO_newx=(BIO *(*)(BIO_METHOD *))f;
- test=BIO_newx(BIO_s_file());
- BIO_set_fp(test,stdout,BIO_NOCLOSE);
- BIO_puts(test,"abd\n\n");
- BIO_free(test);
- DSO_free(d);
- printf("handle in dso number is : %d\n",d->meth_data->num);
- DSO_free(d);
- printf("handle in dso number is : %d\n",d->meth_data->num);
- return 0;
- }
编译
- gcc example4.c -o example4 -L/usr/lib -lssl -lcrypto
程序5:openssl BIO示例
5.1 mem bio
- #include <stdio.h>
- #include <openssl/bio.h>
- int main()
- {
- BIO *b=NULL;
- int len=0;
- char *out=NULL;
- /*mem类型的BIO*/
- b=BIO_new(BIO_s_mem());
- /*写入内容*/
- len=BIO_write(b,"openssl",7);
- len=BIO_printf(b,"%s","bio test");
- /*得到缓冲区中待读取大小*/
- len=BIO_ctrl_pending(b);
- out=(char *)OPENSSL_malloc(len);
- /*读取内容并打印*/
- len=BIO_read(b,out,len);
- printf("%s\n", out);
- /*释放资源*/
- OPENSSL_free(out);
- BIO_free(b);
- return 0;
- }
编译
- gcc example5.1.c -o example5.1 -L/usr/lib -lssl -lcrypto
运行
5.2 file bio
- #include <stdio.h>
- #include <openssl/bio.h>
- int main()
- {
- BIO *b=NULL;
- int len=0,outlen=0;
- char *out=NULL;
- /*创建文件,写入内容*/
- b=BIO_new_file("bf.txt","w");
- len=BIO_write(b,"hello",5);
- len=BIO_printf(b,"%s"," world");
- BIO_free(b);
- /*读取文件内容*/
- b=BIO_new_file("bf.txt","r");
- len=BIO_pending(b);
- len=50;
- out=(char *)OPENSSL_malloc(len);
- len=1;
- while(len>0)
- {
- len=BIO_read(b,out+outlen,1);
- outlen+=len;
- }
- /*打印读取内容*/
- printf("%s\n",out);
- /*释放资源*/
- BIO_free(b);
- free(out);
- return 0;
- }
编译
- gcc example5.2.c -o example5.2 -L/usr/lib -lssl -lcrypto
运行
5.3 socket bio
- //服务器端
- //example5.3s.c
- #include <stdio.h>
- #include <openssl/bio.h>
- #include <string.h>
- int main()
- {
- BIO *b=NULL,*c=NULL;
- int sock,ret,len;
- char *addr=NULL;
- char out[80];
- /*设定端口*/
- sock=BIO_get_accept_socket("2323",0);
- /*建立服务器的BIO*/
- b=BIO_new_socket(sock, BIO_NOCLOSE);
- ret=BIO_accept(sock,&addr);
- /*建立输出到屏幕的BIO*/
- BIO_set_fd(b,ret,BIO_NOCLOSE);
- /*读取并输出*/
- while(1)
- {
- memset(out,0,80);
- len=BIO_read(b,out,80);
- if(out[0]=='q')
- break;
- printf("%s\n",out);
- }
- /*释放资源*/
- BIO_free(b);
- return 0;
- }
编译
- gcc example5.3s.c -o example5.3s -L/usr/lib -lssl -lcrypto
- //客户端
- //example5.3c.c
- #include <stdio.h>
- #include <string.h>
- #include <openssl/bio.h>
- int main()
- {
- BIO *cbio, *out;
- int len;
- char tmpbuf[1024];
- /*建立连接到本地web服务的BIO*/
- cbio = BIO_new_connect("localhost:2323");
- out = BIO_new_fp(stdin, BIO_NOCLOSE);
- /*发出连接请求*/
- if(BIO_do_connect(cbio) <= 0)
- {
- fprintf(stderr, "Error connecting to server\n");
- }
- /*发送消息*/
- BIO_puts(cbio, "GET / HTTP/1.0\n\n");
- while(1)
- {
- /*接收输入*/
- memset(tmpbuf,0,1024);
- scanf("%s",&tmpbuf);
- len=strlen(tmpbuf);
- BIO_write(out, tmpbuf, len);
- /*发送*/
- len = BIO_write(cbio, tmpbuf, len);
- if(len <= 0 || tmpbuf[0]=='q')
- break;
- }
- /*释放资源*/
- BIO_free(cbio);
- BIO_free(out);
- return 0;
- }
编译
- gcc example5.3c.c -o example5.3c -L/usr/lib -lssl -lcrypto
运行
5.4 md BIO
- /*本示例用md BIO对字符串"opessl"进行md5摘要*/
- #include <stdio.h>
- #include <openssl/bio.h>
- #include <openssl/evp.h>
- int main()
- {
- BIO *bmd=NULL,*b=NULL;
- const EVP_MD *md=EVP_md5();
- int len;
- char tmp[1024];
- /*创建一个md BIO*/
- bmd=BIO_new(BIO_f_md());
- /*设置md BIO 为md5 BIO*/
- BIO_set_md(bmd,md);
- /*创建一个null BIO*/
- b= BIO_new(BIO_s_null());
- /*构造BIO链,md5 BIO在顶部*/
- b=BIO_push(bmd,b);
- /*将字符串送入BIO做摘要*/
- len=BIO_write(b,"openssl",7);
- /*将摘要结果写入tmp缓冲区并输出*/
- len=BIO_gets(b,tmp,1024);
- puts(tmp);
- BIO_free(b);
- return 0;
- }
编译
- gcc example5.4.c -o example5.4 -L/usr/lib -lssl -lcrypto
运行
5.5 ssl BIO
- #include <stdio.h>
- #include <openssl/bio.h>
- #include <openssl/ssl.h>
- int main()
- {
- BIO *sbio, *out;
- int len;
- char tmpbuf[1024];
- SSL_CTX *ctx;
- SSL *ssl;
- SSLeay_add_ssl_algorithms();
- OpenSSL_add_all_algorithms();
- ctx = SSL_CTX_new(SSLv3_client_method());
- sbio = BIO_new_ssl_connect(ctx);
- BIO_get_ssl(sbio, &ssl);
- if(!ssl)
- {
- fprintf(stderr, "Can not locate SSL pointer\n");
- return 0;
- }
- SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
- BIO_set_conn_hostname(sbio, "mybank.icbc.com.cn:https");
- out = BIO_new_fp(stdout, BIO_NOCLOSE);
- BIO_printf(out,"链接中….\n");
- if(BIO_do_connect(sbio) <= 0)
- {
- fprintf(stderr, "Error connecting to server\n");
- return 0;
- }
- if(BIO_do_handshake(sbio) <= 0)
- {
- fprintf(stderr, "Error establishing SSL connection\n");
- return 0;
- }
- BIO_puts(sbio, "GET / HTTP/1.0\n\n");
- for(;;)
- {
- len = BIO_read(sbio, tmpbuf, 1024);
- if(len <= 0) break;
- BIO_write(out, tmpbuf, len);
- }
- BIO_free_all(sbio);
- BIO_free(out);
- return 0;
- }
编译
- gcc example5.5.c -o example5.5 -L/usr/lib -lssl -lcrypto
运行
程序6:openssl配置文件示例
6.1
- #include <stdio.h>
- #include <openssl/conf.h>
- int main()
- {
- CONF *conf;
- long eline,result;
- int ret;
- char *p;
- BIO *bp;
- conf=NCONF_new(NULL);
- /*打开配置文件*/
- #if 0
- bp=BIO_new_file("openssl.cnf","r");
- NCONF_load_bio(conf,bp,&eline);
- #else
- ret=NCONF_load(conf,"openssl.cnf",&eline);
- if(ret!=1)
- {
- printf("err!\n");
- return -1;
- }
- #endif
- /*读取配置并打印*/
- p=NCONF_get_string(conf,NULL,"certs");
- if(p==NULL)
- printf("no global certs info\n");
- p=NCONF_get_string(conf,"CA_default","certs");
- printf("%s\n",p);
- p=NCONF_get_string(conf,"CA_default","default_days");
- printf("%s\n",p);
- ret=NCONF_get_number_e(conf,"CA_default","default_days",&result);
- printf("%d\n",result);
- ret=NCONF_get_number(conf,"CA_default","default_days",&result);
- printf("%d\n",result);
- /*释放资源*/
- NCONF_free(conf);
- return 0;
- }
编译
- gcc example6.1.c -o example6.1 -L/usr/lib -lssl -lcrypto
运行
6.2
- #include <stdio.h>
- #include <openssl/conf.h>
- int main()
- {
- CONF *conf;
- BIO *bp;
- STACK_OF(CONF_VALUE) *v;
- CONF_VALUE *one;
- int i,num;
- long eline;
- /*打开并加载配置文件*/
- conf=NCONF_new(NULL);
- bp=BIO_new_file("openssl.cnf","r");
- if(bp==NULL)
- {
- printf("err!\n");
- return -1;
- }
- NCONF_load_bio(conf,bp,&eline);
- /*读取配置信息并打印*/
- v=NCONF_get_section(conf,"CA_default");
- num=sk_CONF_VALUE_num(v);
- printf("section CA_default :\n");
- for(i=0; i<num; i++)
- {
- one=sk_CONF_VALUE_value(v,i);
- printf("%s = %s\n",one->name,one->value);
- }
- /*释放资源*/
- BIO_free(bp);
- return 0;
- }
编译
- gcc example6.2.c -o example6.2 -L/usr/lib -lssl -lcrypto
运行
程序7:openssl随机数示例
- #include <stdio.h>
- #include <string.h>
- #include <openssl/bio.h>
- #include <openssl/rand.h>
- int main()
- {
- char buf[20];
- const char *p;
- char out[20],filename[50];
- int ret,len;
- BIO *print;
- strcpy(buf,"我的随机数");
- RAND_add(buf,20,strlen(buf));
- strcpy(buf,"23424d");
- RAND_seed(buf,20);
- while(1)
- {
- ret=RAND_status(); /*检测熵值*/
- if(ret==1)
- {
- printf("seeded enough!\n");
- break;
- }
- else
- {
- printf("not enough sedded!\n");
- RAND_poll();
- }
- }
- p=RAND_file_name(filename,50);
- if(p==NULL)
- {
- printf("can not get rand file\n");
- return -1;
- }
- ret=RAND_write_file(p);
- len=RAND_load_file(p,1024);
- ret=RAND_bytes(out, 20);
- if(ret!=1)
- {
- printf("err.\n");
- return -1;
- }
- print=BIO_new(BIO_s_file());
- BIO_set_fp(print,stdout,BIO_NOCLOSE);
- BIO_write(print,out,20);
- BIO_write(print,"\n",2);
- /*释放资源*/
- BIO_free(print);
- RAND_cleanup();
- return 0;
- }
编译
- gcc example7.c -o example7 -L/usr/lib -lssl -lcrypto
运行
程序9:openssl错误处理
- #include <openssl/err.h>
- #include <openssl/bn.h>
- int mycb(const char *a,size_t b,void *c)
- {
- printf("my print : %s\n",a);
- return 0;
- }
- int main()
- {
- BIO *berr;
- unsigned long err;
- const char *file,*data,*efunc,*elib,*ereason,*p;
- int line,flags;
- char estring[500];
- FILE *fp;
- /*
- ERR_load_crypto_strings();
- */
- ERR_load_BIO_strings();
- ERR_clear_error();
- berr=BIO_new(BIO_s_file());
- BIO_set_fp(berr,stdout,BIO_NOCLOSE);
- BIO_new_file("no.exist","r");
- err=ERR_peek_last_error();
- err=ERR_peek_last_error_line(&file,&line);
- printf("ERR_peek_last_error_line err : %ld,file : %s,line: %d\n",err,file,line);
- err=ERR_peek_last_error_line_data(&file,&line,&data,&flags);
- printf("ERR_peek_last_error_line_data err: %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
- err=ERR_peek_error();
- printf("ERR_peek_error err: %ld\n",err);
- err=ERR_peek_error_line(&file,&line);
- printf("ERR_peek_error_line err : %ld,file : %s,line: %d\n",err,file,line);
- err=ERR_peek_error_line_data(&file,&line,&data,&flags);
- printf("ERR_peek_error_line_data err : %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
- err = ERR_get_error_line_data(&file,&line,&data,&flags);
- printf("ERR_get_error_line_data err : %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
- if(err!=0)
- {
- p=ERR_lib_error_string(err);
- printf("ERR_lib_error_string : %s\n",p);
- }
- err=ERR_get_error();
- if(err!=0)
- {
- printf("ERR_get_error err : %ld\n",err);
- efunc=ERR_func_error_string(err);
- printf("err func : %s\n",efunc);
- elib=ERR_lib_error_string(err);
- printf("err lib : %s\n",efunc);
- ereason=ERR_reason_error_string(err);
- printf("err reason : %s\n",efunc);
- efunc=ERR_func_error_string(err);
- printf("err func : %s\n",efunc);
- elib=ERR_lib_error_string(err);
- printf("err lib : %s\n",efunc);
- ereason=ERR_reason_error_string(err);
- printf("err reason : %s\n",efunc);
- ERR_error_string(err,estring);
- printf("ERR_error_string : %s\n",estring);
- ERR_error_string_n(err,estring,sizeof(estring));
- printf("ERR_error_string_n : %s\n",estring);
- }
- err=ERR_get_error_line(&file,&line);
- printf("err file :%s , err line : %d\n",file,line);
- ERR_print_errors(berr);
- BIO_new_file("no.exist2","r");
- fp=fopen("err.log","w");
- ERR_print_errors_fp(fp);
- fclose(fp);
- BIO_new_file("no.exist3","r");
- ERR_print_errors_cb(mycb,NULL);
- ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,
- line);
- ERR_print_errors(berr);
- ERR_load_BN_strings();
- ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,line);
- ERR_print_errors(berr);
- ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,line);
- ERR_set_error_data("set date test!\n",ERR_TXT_STRING);
- err=ERR_set_mark();
- ERR_print_errors(berr);
- ERR_free_strings();
- BIO_free(berr);
- return 0;
- }
编译
- gcc -g example9.c -o example9 -L/usr/lib -lssl -lcrypto
运行
程序10:openssl证书申请
- //example10.1a.c
- #include <stdio.h>
- #include <string.h>
- #include <openssl/x509.h>
- #include <openssl/rsa.h>
- int main()
- {
- X509_REQ *req;
- int ret;
- long version;
- X509_NAME *name;
- EVP_PKEY *pkey;
- RSA *rsa;
- X509_NAME_ENTRY *entry=NULL;
- char bytes[100],mdout[20];
- int len,mdlen;
- int bits=512;
- unsigned long e=RSA_3;
- unsigned char *der,*p;
- FILE *fp;
- const EVP_MD *md;
- X509 *x509;
- BIO *b;
- STACK_OF(X509_EXTENSION) *exts;
- req=X509_REQ_new();
- version=1;
- ret=X509_REQ_set_version(req,version);
- name=X509_NAME_new();
- strcpy(bytes,"openssl");
- len=strlen(bytes);
- entry=X509_NAME_ENTRY_create_by_txt(&entry,"commonName",V_ASN1_UTF8STRING,(unsigned char *)bytes,len);
- X509_NAME_add_entry(name,entry,0,-1);
- strcpy(bytes,"bj");
- len=strlen(bytes);
- entry=X509_NAME_ENTRY_create_by_txt(&entry,"countryName",V_ASN1_UTF8STRING,bytes,len);
- X509_NAME_add_entry(name,entry,1,-1);
- /* subject name */
- ret=X509_REQ_set_subject_name(req,name);
- /* pub key */
- pkey=EVP_PKEY_new();
- rsa=RSA_generate_key(bits,e,NULL,NULL);
- EVP_PKEY_assign_RSA(pkey,rsa);
- ret=X509_REQ_set_pubkey(req,pkey);
- /* attribute */
- strcpy(bytes,"test");
- len=strlen(bytes);
- ret=X509_REQ_add1_attr_by_txt(req,"organizationName",V_ASN1_UTF8STRING,bytes,len);
- strcpy(bytes,"ttt");
- len=strlen(bytes);
- ret=X509_REQ_add1_attr_by_txt(req,"organizationalUnitName",V_ASN1_UTF8STRING,bytes,len);
- md=EVP_sha1();
- ret=X509_REQ_digest(req,md,mdout,&mdlen);
- ret=X509_REQ_sign(req,pkey,md);
- if(!ret)
- {
- printf("sign err!\n");
- X509_REQ_free(req);
- return -1;
- }
- /* 写入文件PEM 格式 */
- b=BIO_new_file("certreq.txt","w");
- PEM_write_bio_X509_REQ(b,req,NULL,NULL);
- BIO_free(b);
- /* DER 编码 */
- len=i2d_X509_REQ(req,NULL);
- der=malloc(len);
- p=der;
- len=i2d_X509_REQ(req,&p);
- OpenSSL_add_all_algorithms();
- ret=X509_REQ_verify(req,pkey);
- if(ret<0)
- {
- printf("verify err.\n");
- }
- fp=fopen("certreq2.txt","wb");
- fwrite(der,1,len,fp);
- fclose(fp);
- free(der);
- X509_REQ_free(req);
- return 0;
- }
编译
- gcc -g example10.1a.c -o example10.1a -L/usr/lib -lssl -lcrypto
运行
- //example10.1b.c
- #include <stdio.h>
- #include <string.h>
- #include <openssl/pem.h>
- int main()
- {
- BIO *in;
- X509_REQ *req=NULL,**req2=NULL;
- FILE *fp;
- unsigned char buf[1024];
- char *p;
- int len;
- /*PEM 格式解码*/
- in=BIO_new_file("certreq.txt","r");
- req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
- if(req==NULL)
- {
- printf("DER解码错误!\n");
- }
- else
- {
- printf("DER解码成功!\n");
- }
- /*DER 格式解码*/
- fp=fopen("certreq2.txt","r");
- fread(buf,1,1024,fp);
- fclose(fp);
- p=buf;
- len=strlen(buf);
- req2=(X509_REQ **)malloc(sizeof(X509_REQ *));
- d2i_X509_REQ(req2,&p,len);
- if(*req2==NULL)
- {
- printf("DER解码错误!\n");
- }
- else
- {
- printf("DER解码成功!\n");
- }
- X509_REQ_free(*req2);
- free(req2);
- return 0;
- }
编译
- gcc -g example10.1b.c -o example10.1b -L/usr/lib -lssl -lcrypto
运行
程序11:openssl CRL(证书撤销列表)示例
- #include <stdio.h>
- #include <openssl/x509.h>
- int main()
- {
- int ret,len;
- unsigned char *buf,*p;
- unsigned long e=RSA_3;
- FILE *fp;
- time_t t;
- X509_NAME *issuer;
- ASN1_TIME *lastUpdate,*nextUpdate,*rvTime;
- X509_CRL *crl=NULL;
- X509_REVOKED *revoked;
- EVP_PKEY *pkey;
- ASN1_INTEGER *serial;
- RSA *r;
- BIGNUM *bne;
- BIO *bp;
- /* 生成密钥*/
- bne=BN_new();
- ret=BN_set_word(bne,e);
- r=RSA_new();
- ret=RSA_generate_key_ex(r,1024,bne,NULL);
- if(ret!=1)
- {
- printf("RSA_generate_key_ex err!\n");
- return -1;
- }
- pkey=EVP_PKEY_new();
- EVP_PKEY_assign_RSA(pkey,r);
- /* 设置版本*/
- crl=X509_CRL_new();
- ret=X509_CRL_set_version(crl,3);
- /* 设置颁发者*/
- issuer=X509_NAME_new();
- ret=X509_NAME_add_entry_by_NID(issuer,NID_commonName,V_ASN1_PRINTABLESTRING, "CRL issuer",10,-1,0);
- ret=X509_CRL_set_issuer_name(crl,issuer);
- /* 设置上次发布时间*/
- lastUpdate=ASN1_TIME_new();
- t=time(NULL);
- ASN1_TIME_set(lastUpdate,t);
- ret=X509_CRL_set_lastUpdate(crl,lastUpdate);
- /* 设置下次发布时间*/
- nextUpdate=ASN1_TIME_new();
- t=time(NULL);
- ASN1_TIME_set(nextUpdate,t+1000);
- ret=X509_CRL_set_nextUpdate(crl,nextUpdate);
- /* 添加被撤销证书序列号*/
- revoked=X509_REVOKED_new();
- serial=ASN1_INTEGER_new();
- ret=ASN1_INTEGER_set(serial,1000);
- ret=X509_REVOKED_set_serialNumber(revoked,serial);
- /* 设置吊销日期*/
- rvTime=ASN1_TIME_new();
- t=time(NULL);
- ASN1_TIME_set(rvTime,t+2000);
- ret=X509_CRL_set_nextUpdate(crl,rvTime);
- ret=X509_REVOKED_set_revocationDate(revoked,rvTime);
- ret=X509_CRL_add0_revoked(crl,revoked);
- /* 排序*/
- ret=X509_CRL_sort(crl);
- /* 签名*/
- ret=X509_CRL_sign(crl,pkey,EVP_md5());
- /* 写入文件*/
- bp=BIO_new(BIO_s_file());
- BIO_set_fp(bp,stdout,BIO_NOCLOSE);
- X509_CRL_print(bp,crl);
- len=i2d_X509_CRL(crl,NULL);
- buf=malloc(len+10);
- p=buf;
- len=i2d_X509_CRL(crl,&p);
- fp=fopen("crl.crl","wb");
- fwrite(buf,1,len,fp);
- fclose(fp);
- BIO_free(bp);
- X509_CRL_free(crl);
- free(buf);
- getchar();
- return 0;
- }
编译
- gcc -g example11.c -o example11 -L/usr/lib -lssl -lcrypto
运行
程序12:openssl 证书校验示例
- /**
- * 步骤:
- * 1)初始化环境
- * a.新建证书存储区X509_STORE_new()
- * b.新建证书校验上下文X509_STORE_CTX_new()
- *
- * 2)导入根证书
- * a.读取CA证书,从DER编码格式化为X509结构d2i_X509()
- * b.将CA证书导入证书存储区X509_STORE_add_cert()
- *
- * 3)导入要校验的证书test
- * a.读取证书test,从DER编码格式化为X509结构d2i_X509()
- * b.在证书校验上下文初始化证书test,X509_STORE_CTX_init()
- * c.校验X509_verify_cert
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <openssl/evp.h>
- #include <openssl/x509.h>
- #define CERT_PATH "/root/workspace/caroot"
- #define ROOT_CERT "ca.crt"
- #define WIN71H "client.crt"
- #define WIN71Y "win71y.cer"
- #define GET_DEFAULT_CA_CERT(str) sprintf(str, "%s/%s", CERT_PATH, ROOT_CERT)
- #define GET_CUSTOM_CERT(str, path, name) sprintf(str, "%s/%s", path, name)
- #define MAX_LEGTH 4096
- int my_load_cert(unsigned char *str, unsigned long *str_len,
- const char *verify_cert, const unsigned int cert_len)
- {
- FILE *fp;
- fp = fopen(verify_cert, "rb");
- if ( NULL == fp)
- {
- fprintf(stderr, "fopen fail\n");
- return -1;
- }
- *str_len = fread(str, 1, cert_len, fp);
- fclose(fp);
- return 0;
- }
- X509 *der_to_x509(const unsigned char *der_str, unsigned int der_str_len)
- {
- X509 *x509;
- x509 = d2i_X509(NULL, &der_str, der_str_len);
- if ( NULL == x509 )
- {
- fprintf(stderr, "d2i_X509 fail\n");
- return NULL;
- }
- return x509;
- }
- int x509_verify()
- {
- int ret;
- char cert[MAX_LEGTH];
- unsigned char user_der[MAX_LEGTH];
- unsigned long user_der_len;
- X509 *user = NULL;
- unsigned char ca_der[MAX_LEGTH];
- unsigned long ca_der_len;
- X509 *ca = NULL;
- X509_STORE *ca_store = NULL;
- X509_STORE_CTX *ctx = NULL;
- STACK_OF(X509) *ca_stack = NULL;
- /* x509初始化 */
- ca_store = X509_STORE_new();
- ctx = X509_STORE_CTX_new();
- /* root ca*/
- GET_DEFAULT_CA_CERT(cert);
- /* 从文件中读取 */
- my_load_cert(ca_der, &ca_der_len, cert, MAX_LEGTH);
- /* DER编码转X509结构 */
- ca = der_to_x509(ca_der, ca_der_len);
- /* 加入证书存储区 */
- ret = X509_STORE_add_cert(ca_store, ca);
- if ( ret != 1 )
- {
- fprintf(stderr, "X509_STORE_add_cert fail, ret = %d\n", ret);
- goto EXIT;
- }
- /* 需要校验的证书 */
- GET_CUSTOM_CERT(cert, CERT_PATH, WIN71H);
- my_load_cert(user_der, &user_der_len, cert, MAX_LEGTH);
- user = der_to_x509(user_der, user_der_len);
- ret = X509_STORE_CTX_init(ctx, ca_store, user, ca_stack);
- if ( ret != 1 )
- {
- fprintf(stderr, "X509_STORE_CTX_init fail, ret = %d\n", ret);
- goto EXIT;
- }
- //openssl-1.0.1c/crypto/x509/x509_vfy.h
- ret = X509_verify_cert(ctx);
- if ( ret != 1 )
- {
- fprintf(stderr, "X509_verify_cert fail, ret = %d, error id = %d, %s\n",
- ret, ctx->error, X509_verify_cert_error_string(ctx->error));
- goto EXIT;
- }
- EXIT:
- X509_free(user);
- X509_free(ca);
- X509_STORE_CTX_cleanup(ctx);
- X509_STORE_CTX_free(ctx);
- X509_STORE_free(ca_store);
- return ret == 1 ? 0 : -1;
- }
- int main()
- {
- OpenSSL_add_all_algorithms();
- x509_verify();
- return 0;
- }
编译
- gcc -g example12.c -o example12 -L/usr/local/ssl/lib -lssl -lcrypto -I/usr/local/ssl/include
OpenSSL编程的更多相关文章
- Openssl编程--源码分析
Openssl编程 赵春平 著 Email: forxy@126.com 第一章 基础知识 8 1.1 对称算法 8 1.2 摘要算法 9 1.3 公钥算法 9 1.4 回调函数 11 第二章 ope ...
- OPENSSL编程 (secure shell, ssh)
很好的 OPENSSL编程 教程,名字就叫“OPENSSL编程” 它里面还有很多关于密码学的东西. http://www.pengshuo.me http://www.pengshuo.me/2014 ...
- 基于openeuler的openssl编程
------------恢复内容开始------------ 一.编译环境 我下载好之后默认安装了openssl,若未安装的可输入以下命令: wget https://www.openssl.org/ ...
- OPENSSL编程入门学习
相关学习资料 http://bbs.pediy.com/showthread.php?t=92649 https://www.openssl.org https://www.google.com.hk ...
- 笔记整理——使用openssl编程
error: openssl 的所有解决方案 (2013/6/22 17:39:00) error: openssl/crypto.h: No such file or directory 解决方案 ...
- OPENSSL编程 第二十章 椭圆曲线
20.1 ECC介绍 椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则.椭圆曲线在如下两个域中定义:Fp域和F2m域. Fp域,素数域,p为素数: F2m域:特征为2的有限域,称之为二 ...
- OPENSSL编程起步
原文链接: http://blog.csdn.net/itmes/article/details/7711076 WINDOWS平台下OPENSSL的编译和安装使用 OPENSSL是开放源代码的,可以 ...
- openssl 编程
背景: 生成私钥.公钥 --> 生成AES-key seed[32], iv[16] --> 公钥加密ASE-key, IV,传给Server --> Server用私钥解密,得到A ...
- linux openssl 编程 Client端
相关配置等请參看上一篇关于server端文章:http://blog.csdn.net/pingd/article/details/47805349 1.Client端源代码: openssl_cli ...
随机推荐
- SQL Server占用服务器内存过高
SQL Server对服务器内存的使用策略是用多少内存就占用多少内存,只用在服务器内存不足时,才会释放一点占用的内存,所以SQL Server 服务器内存往往会占用很高. 查看内存状态: DBCC M ...
- django 更新 模板语言
Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Django的模板语言中按此语法使用:{{ 变量名 ...
- selenium+python自动化84-chrome手机wap模式(登录淘宝页面)
前言 chrome手机wap模式登录淘宝页面,点击验证码无效问题解决. 切换到wap模式,使用TouchActions模块用tap方法触摸 我的环境 chrome 62 chromedriver 2. ...
- 3.2_k-近邻算法案例分析
k-近邻算法案例分析 本案例使用最著名的”鸢尾“数据集,该数据集曾经被Fisher用在经典论文中,目前作为教科书般的数据样本预存在Scikit-learn的工具包中. 读入Iris数据集细节资 ...
- 网络层-IP地址
以下内容是IPv4 IP地址长度32位,Java里面一个int的长度,总共分为5类IP地址 1:分类编址 A类IP地址0开头: A类有31个位置可以变化,总数是2^31个, [(0 ...
- sqlserver导入导出数据库结构及创建用户分配权限
1.创建用户分配权限 https://www.cnblogs.com/jennyjiang-00/p/5803140.html 2.sqlserver2008导出表结构和表数据 导出表结构 htt ...
- 28. 表单css样式定义格式
form>table>tbody>tr>td{padding:5px;font-size:14px;font-family:"Microsoft YaHei" ...
- HTML5 Canvas ( 文字的度量 ) measureText
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- leetcode29
class Solution { public int divide(int dividend, int divisor) { if (dividend == Integer.MIN_VALUE &a ...
- c++变量声明、定义,const变量
变量声明和定义的主要区别: 声明不分配存储空间,定义分配存储空间. 变量可以声明多次,但只能定义一次(一个变量只能在一个源文件中定义) 声明通常放在头文件(.h)中,定义放在源文件(.cpp)中 变量 ...