简介

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、资源下载

  1. http://www.openssl.org/source/openssl-1.0.0e.tar.gz

2、编译安装

tar –zxvf openssl-1.0.0e.tar.gz
  1. cd openssl-1.0.0e
  1.  
  1. ./config
  2. make
  3. make install

API文档

  1. http://www.openssl.org/docs/crypto/crypto.html
  2. http://www.openssl.org/docs/ssl/ssl.html

编程示例

程序1:openssl堆栈示例

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <openssl/safestack.h>
  5. #define sk_Student_new(st) SKM_sk_new(Student, (st))
  6. #define sk_Student_new_null() SKM_sk_new_null(Student)
  7. #define sk_Student_free(st) SKM_sk_free(Student, (st))
  8. #define sk_Student_num(st) SKM_sk_num(Student, (st))
  9. #define sk_Student_value(st, i) SKM_sk_value(Student, (st), (i))
  10. #define sk_Student_set(st, i, val) SKM_sk_set(Student, (st), (i), (val))
  11. #define sk_Student_zero(st) SKM_sk_zero(Student, (st))
  12. #define sk_Student_push(st, val) SKM_sk_push(Student, (st), (val))
  13. #define sk_Student_unshift(st, val) SKM_sk_unshift(Student, (st), (val))
  14. #define sk_Student_find(st, val) SKM_sk_find(Student, (st), (val))
  15. #define sk_Student_delete(st, i) SKM_sk_delete(Student, (st), (i))
  16. #define sk_Student_delete_ptr(st, ptr) SKM_sk_delete_ptr(Student, (st), (ptr))
  17. #define sk_Student_insert(st, val, i) SKM_sk_insert(Student, (st), (val), (i))
  18. #define sk_Student_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(Student, (st), (cmp))
  19. #define sk_Student_dup(st) SKM_sk_dup(Student, st)
  20. #define sk_Student_pop_free(st, free_func) SKM_sk_pop_free(Student, (st), (free_func))
  21. #define sk_Student_shift(st) SKM_sk_shift(Student, (st))
  22. #define sk_Student_pop(st) SKM_sk_pop(Student, (st))
  23. #define sk_Student_sort(st) SKM_sk_sort(Student, (st))
  24.  
  25. typedef struct Student_st
  26. {
  27. char *name;
  28. int age;
  29. char *otherInfo;
  30. } Student;
  31.  
  32. typedef STACK_OF(Student) Students;
  33.  
  34. Student *Student_Malloc()
  35. {
  36. Student *a=malloc(sizeof(Student));
  1. a->name=(char *)malloc(sizeof(char)*20);
  2. strcpy(a->name,"zcp");
  3. a->otherInfo=(char *)malloc(sizeof(char)*20);
  1. strcpy(a->otherInfo,"no info");
  1. return a;
  2. }
  3.  
  4. void Student_Free(Student *a)
  5. {
  6. free(a->name);
  7. free(a->otherInfo);
  8. free(a);
  9. }
  10. static int Student_cmp(Student *a,Student *b)
  11. {
  12. int ret;
  13. ret=strcmp(a->name,b->name); /* 只比较关键字 */
  14. return ret;
  15. }
  16.  
  17. int main()
  18. {
  19. Students *s,*snew;
  20. Student *s1,*one,*s2;
  21. int i,num;
  22. s=sk_Student_new_null(); /* 新建一个堆栈对象 */
  23. snew=sk_Student_new(Student_cmp); /* 新建一个堆栈对象 */
  1. s2=Student_Malloc();
  2. sk_Student_push(snew,s2);
  3. i=sk_Student_find(snew,s2);
  1. s1=Student_Malloc();
  2. sk_Student_push(s,s1);
  3. num=sk_Student_num(s);
  4. for(i=0; i<num; i++)
  5. {
  6. one=sk_Student_value(s,i);
  7. printf("student name : %s\n",one->name);
  8. printf("sutdent age : %d\n",one->age);
  9. printf("student otherinfo : %s\n\n\n",one->otherInfo);
  10. }
  1. sk_Student_pop_free(s,Student_Free);
  2. sk_Student_pop_free(snew,Student_Free);
  3.  
  4. return 0;
  5. }

编译

  1. gcc example1.c -o example1 -L/usr/lib -lssl -lcrypto

运行

程序2:openssl哈希表示例

  1. #include <string.h>
  2. #include <openssl/lhash.h>
  3.  
  4. typedef struct Student_st
  5. {
  6. char name[20];
  7. int age;
  8. char otherInfo[200];
  9. } Student;
  10.  
  11. static int Student_cmp(const void *a, const void *b)
  12. {
  13. char *namea=((Student *)a)->name;
  14. char *nameb=((Student *)b)->name;
  15. return strcmp(namea,nameb);
  16. }
  17.  
  18. /* 打印每个值*/
  19. static void PrintValue(Student *a)
  20. {
  21. printf("name :%s\n",a->name);
  22. printf("age :%d\n",a->age);
  23. printf("otherInfo : %s\n",a->otherInfo);
  24. }
  25.  
  26. static void PrintValue_arg(Student *a,void *b)
  27. {
  28. int flag=0;
  29.  
  30. flag=*(int *)b;
  31. printf("用户输入参数为:%d\n",flag);
  32. printf("name :%s\n",a->name);
  33. printf("age :%d\n",a->age);
  34. printf("otherInfo : %s\n",a->otherInfo);
  35. }
  36.  
  37. int main()
  38. {
  39. int flag=11;
  40. _LHASH *h;
  41. Student s1= {"zcp",28,"hu bei"},
  42. s2= {"forxy",28,"no info"},
  43. s3= {"skp",24,"student"},
  44. s4= {"zhao_zcp",28,"zcp's name"},
  45. *s5;
  46. void *data;
  47.  
  48. /*创建哈希表*/
  49. h=lh_new(NULL,Student_cmp);
  50. if(h==NULL)
  51. {
  52. printf("err.\n");
  53. return -1;
  54. }
  55. /*将数据插入哈希表*/
  56. data=&s1;
  57. lh_insert(h,data);
  58. data=&s2;
  59. lh_insert(h,data);
  60. data=&s3;
  61. lh_insert(h,data);
  62. data=&s4;
  63. lh_insert(h,data);
  64.  
  65. /*遍历打印*/
  66. lh_doall(h,PrintValue);
  67. lh_doall_arg(h,PrintValue_arg,(void *)(&flag));
  68.  
  69. /*查找数据*/
  70. data=lh_retrieve(h,(const void*)"skp");
  71. if(data==NULL)
  72. {
  73. printf("can not find skp!\n");
  74. lh_free(h);
  75. return -1;
  76. }
  77. else
  78. {
  79. s5=data;
  80. printf("\n\nstudent name : %s\n",s5->name);
  81. printf("sutdent age : %d\n",s5->age);
  82. printf("student otherinfo : %s\n",s5->otherInfo);
  83. lh_free(h);
  84. }
  85.  
  86. getchar();
  87. return 0;
  88. }

编译

  1. gcc example2.c -o example2 -L/usr/lib -lssl -lcrypto

运行

程序3:openssl内存管理示例

  1. #include <openssl/crypto.h>
  2. #include <openssl/bio.h>
  3.  
  4. int main()
  5. {
  6. char *p;
  7. BIO *b;
  8. CRYPTO_malloc_debug_init();
  9. CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
  10. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); /*开户内存记录*/
  11.  
  12. p=OPENSSL_malloc(4);
  13. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);/*关闭内存记录*/
  14. b=BIO_new_file("leak.log","w");
  15. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  16. CRYPTO_mem_leaks(b); /*将内存泄露输出到FILE中*/
  17.  
  18. OPENSSL_free(p);
  19. BIO_free(b);
  20. return 0;
  21. }

编译

  1. gcc example3.c -o example3 -L/usr/lib -lssl -lcrypto

运行

程序4:动态模块加载

  1. #include <openssl/dso.h>
  2. #include <openssl/bio.h>
  3. #include <openssl/safestack.h>
  4.  
  5. int main()
  6. {
  7. DSO *d;
  8. void (*f)();
  9. BIO *(*BIO_newx)(BIO_METHOD *a);
  10. BIO *test;
  11. char *load_name;
  12. const char *loaded_name;
  13. int flags;
  14.  
  15. d=DSO_new();
  16. #if 0
  17. DSO_set_name_converter
  18. DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL);
  19. DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NAME_TRANSLATION_EXT_ONLY,NULL);
  20. DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_GLOBAL_SYMBOLS,NULL);
  21. /* 最好写成libeay32而不是libeay32.dll, 除非前面调用了DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL)否则它会加载libeay32.dll.dll
  22. */
  23. load_name=DSO_merge(d,"libeay32","D:\\zcp\\OpenSSL\\openssl-0.9.8b\\out32dll\\Debug");
  24. #endif
  25. d=DSO_load(d,"libeay32",NULL,0);
  26. if(d==NULL)
  27. {
  28. printf("err");
  29. return -1;
  30. }
  31. loaded_name=DSO_get_loaded_filename(d);
  32. if(loaded_name!=NULL)
  33. {
  34. printf("loaded file is %s\n",loaded_name);
  35.  
  36. }
  37. flags=DSO_flags(d);
  38. printf("current falgs is %d\n",flags);
  39. DSO_up_ref(d);
  40. f=(void (*)())DSO_bind_var(d,"BIO_new");
  41. BIO_newx=(BIO *(*)(BIO_METHOD *))f;
  42. test=BIO_newx(BIO_s_file());
  43. BIO_set_fp(test,stdout,BIO_NOCLOSE);
  44. BIO_puts(test,"abd\n\n");
  45. BIO_free(test);
  46. DSO_free(d);
  47. printf("handle in dso number is : %d\n",d->meth_data->num);
  48. DSO_free(d);
  49. printf("handle in dso number is : %d\n",d->meth_data->num);
  50. return 0;
  51. }

编译

  1. gcc example4.c -o example4 -L/usr/lib -lssl -lcrypto

程序5:openssl BIO示例

5.1 mem bio

  1. #include <stdio.h>
  2. #include <openssl/bio.h>
  3.  
  4. int main()
  5. {
  6. BIO *b=NULL;
  7. int len=0;
  8. char *out=NULL;
  9.  
  10. /*mem类型的BIO*/
  11. b=BIO_new(BIO_s_mem());
  12.  
  13. /*写入内容*/
  14. len=BIO_write(b,"openssl",7);
  15. len=BIO_printf(b,"%s","bio test");
  16.  
  17. /*得到缓冲区中待读取大小*/
  18. len=BIO_ctrl_pending(b);
  19. out=(char *)OPENSSL_malloc(len);
  20.  
  21. /*读取内容并打印*/
  22. len=BIO_read(b,out,len);
  23. printf("%s\n", out);
  24.  
  25. /*释放资源*/
  26. OPENSSL_free(out);
  27. BIO_free(b);
  28. return 0;
  29. }

编译

  1. gcc example5.1.c -o example5.1 -L/usr/lib -lssl -lcrypto

运行

5.2 file bio

  1. #include <stdio.h>
  2. #include <openssl/bio.h>
  3.  
  4. int main()
  5. {
  6. BIO *b=NULL;
  7. int len=0,outlen=0;
  8. char *out=NULL;
  9.  
  10. /*创建文件,写入内容*/
  11. b=BIO_new_file("bf.txt","w");
  12. len=BIO_write(b,"hello",5);
  13. len=BIO_printf(b,"%s"," world");
  14. BIO_free(b);
  15.  
  16. /*读取文件内容*/
  17. b=BIO_new_file("bf.txt","r");
  18. len=BIO_pending(b);
  19. len=50;
  20. out=(char *)OPENSSL_malloc(len);
  21. len=1;
  22. while(len>0)
  23. {
  24. len=BIO_read(b,out+outlen,1);
  25. outlen+=len;
  26. }
  27.  
  28. /*打印读取内容*/
  29. printf("%s\n",out);
  30.  
  31. /*释放资源*/
  32. BIO_free(b);
  33. free(out);
  34. return 0;
  35. }

编译

  1. gcc example5.2.c -o example5.2 -L/usr/lib -lssl -lcrypto

运行

5.3 socket bio

  1. //服务器端
  1. //example5.3s.c
  2. #include <stdio.h>
  3. #include <openssl/bio.h>
  4. #include <string.h>
  5.  
  6. int main()
  7. {
  8. BIO *b=NULL,*c=NULL;
  9. int sock,ret,len;
  10. char *addr=NULL;
  11. char out[80];
  12.  
  13. /*设定端口*/
  14. sock=BIO_get_accept_socket("2323",0);
  15.  
  16. /*建立服务器的BIO*/
  17. b=BIO_new_socket(sock, BIO_NOCLOSE);
  18. ret=BIO_accept(sock,&addr);
  19.  
  20. /*建立输出到屏幕的BIO*/
  21. BIO_set_fd(b,ret,BIO_NOCLOSE);
  22.  
  23. /*读取并输出*/
  24. while(1)
  25. {
  26. memset(out,0,80);
  27. len=BIO_read(b,out,80);
  28. if(out[0]=='q')
  29. break;
  30. printf("%s\n",out);
  31. }
  32.  
  33. /*释放资源*/
  34. BIO_free(b);
  35. return 0;
  36. }

编译

  1. gcc example5.3s.c -o example5.3s -L/usr/lib -lssl -lcrypto
  1. //客户端
  2. //example5.3c.c
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <openssl/bio.h>
  6. int main()
  7. {
  8. BIO *cbio, *out;
  9. int len;
  10. char tmpbuf[1024];
  11.  
  12. /*建立连接到本地web服务的BIO*/
  13. cbio = BIO_new_connect("localhost:2323");
  14. out = BIO_new_fp(stdin, BIO_NOCLOSE);
  15.  
  16. /*发出连接请求*/
  17. if(BIO_do_connect(cbio) <= 0)
  18. {
  19. fprintf(stderr, "Error connecting to server\n");
  20. }
  21.  
  22. /*发送消息*/
  23. BIO_puts(cbio, "GET / HTTP/1.0\n\n");
  24. while(1)
  25. {
  26. /*接收输入*/
  27. memset(tmpbuf,0,1024);
  28. scanf("%s",&tmpbuf);
  29. len=strlen(tmpbuf);
  30. BIO_write(out, tmpbuf, len);
  31.  
  32. /*发送*/
  33. len = BIO_write(cbio, tmpbuf, len);
  34. if(len <= 0 || tmpbuf[0]=='q')
  35. break;
  36. }
  37.  
  38. /*释放资源*/
  39. BIO_free(cbio);
  40. BIO_free(out);
  41. return 0;
  42. }

编译

  1. gcc example5.3c.c -o example5.3c -L/usr/lib -lssl -lcrypto

运行

5.4 md BIO

  1. /*本示例用md BIO对字符串"opessl"进行md5摘要*/
  2. #include <stdio.h>
  3. #include <openssl/bio.h>
  4. #include <openssl/evp.h>
  5.  
  6. int main()
  7. {
  8. BIO *bmd=NULL,*b=NULL;
  9. const EVP_MD *md=EVP_md5();
  10. int len;
  11. char tmp[1024];
  12.  
  13. /*创建一个md BIO*/
  14. bmd=BIO_new(BIO_f_md());
  15.  
  16. /*设置md BIO 为md5 BIO*/
  17. BIO_set_md(bmd,md);
  18.  
  19. /*创建一个null BIO*/
  20. b= BIO_new(BIO_s_null());
  21.  
  22. /*构造BIO链,md5 BIO在顶部*/
  23. b=BIO_push(bmd,b);
  24.  
  25. /*将字符串送入BIO做摘要*/
  26. len=BIO_write(b,"openssl",7);
  27.  
  28. /*将摘要结果写入tmp缓冲区并输出*/
  29. len=BIO_gets(b,tmp,1024);
  30. puts(tmp);
  31.  
  32. BIO_free(b);
  33. return 0;
  34. }

编译

  1. gcc example5.4.c -o example5.4 -L/usr/lib -lssl -lcrypto

运行

5.5 ssl BIO

  1. #include <stdio.h>
  2. #include <openssl/bio.h>
  3. #include <openssl/ssl.h>
  4.  
  5. int main()
  6. {
  7. BIO *sbio, *out;
  8. int len;
  9. char tmpbuf[1024];
  10. SSL_CTX *ctx;
  11. SSL *ssl;
  12.  
  13. SSLeay_add_ssl_algorithms();
  14. OpenSSL_add_all_algorithms();
  15. ctx = SSL_CTX_new(SSLv3_client_method());
  16. sbio = BIO_new_ssl_connect(ctx);
  17. BIO_get_ssl(sbio, &ssl);
  18. if(!ssl)
  19. {
  20. fprintf(stderr, "Can not locate SSL pointer\n");
  21. return 0;
  22. }
  23. SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  24. BIO_set_conn_hostname(sbio, "mybank.icbc.com.cn:https");
  25. out = BIO_new_fp(stdout, BIO_NOCLOSE);
  26. BIO_printf(out,"链接中….\n");
  27. if(BIO_do_connect(sbio) <= 0)
  28. {
  29. fprintf(stderr, "Error connecting to server\n");
  30. return 0;
  31. }
  32. if(BIO_do_handshake(sbio) <= 0)
  33. {
  34. fprintf(stderr, "Error establishing SSL connection\n");
  35. return 0;
  36. }
  37. BIO_puts(sbio, "GET / HTTP/1.0\n\n");
  38. for(;;)
  39. {
  40. len = BIO_read(sbio, tmpbuf, 1024);
  41. if(len <= 0) break;
  42. BIO_write(out, tmpbuf, len);
  43. }
  44. BIO_free_all(sbio);
  45. BIO_free(out);
  46. return 0;
  47. }

编译

  1. gcc example5.5.c -o example5.5 -L/usr/lib -lssl -lcrypto

运行

程序6:openssl配置文件示例

6.1

  1. #include <stdio.h>
  2. #include <openssl/conf.h>
  3.  
  4. int main()
  5. {
  6. CONF *conf;
  7. long eline,result;
  8. int ret;
  9. char *p;
  10. BIO *bp;
  11. conf=NCONF_new(NULL);
  12.  
  13. /*打开配置文件*/
  14. #if 0
  15. bp=BIO_new_file("openssl.cnf","r");
  16. NCONF_load_bio(conf,bp,&eline);
  17. #else
  18. ret=NCONF_load(conf,"openssl.cnf",&eline);
  19. if(ret!=1)
  20. {
  21. printf("err!\n");
  22. return -1;
  23. }
  24. #endif
  25.  
  26. /*读取配置并打印*/
  27. p=NCONF_get_string(conf,NULL,"certs");
  28. if(p==NULL)
  29. printf("no global certs info\n");
  30. p=NCONF_get_string(conf,"CA_default","certs");
  31. printf("%s\n",p);
  32.  
  33. p=NCONF_get_string(conf,"CA_default","default_days");
  34. printf("%s\n",p);
  35.  
  36. ret=NCONF_get_number_e(conf,"CA_default","default_days",&result);
  37. printf("%d\n",result);
  38.  
  39. ret=NCONF_get_number(conf,"CA_default","default_days",&result);
  40. printf("%d\n",result);
  41.  
  42. /*释放资源*/
  43. NCONF_free(conf);
  44.  
  45. return 0;
  46. }

编译

  1. gcc example6.1.c -o example6.1 -L/usr/lib -lssl -lcrypto

运行

6.2

  1. #include <stdio.h>
  2. #include <openssl/conf.h>
  3.  
  4. int main()
  5. {
  6. CONF *conf;
  7. BIO *bp;
  8. STACK_OF(CONF_VALUE) *v;
  9. CONF_VALUE *one;
  10. int i,num;
  11. long eline;
  12.  
  13. /*打开并加载配置文件*/
  14. conf=NCONF_new(NULL);
  15. bp=BIO_new_file("openssl.cnf","r");
  16. if(bp==NULL)
  17. {
  18. printf("err!\n");
  19. return -1;
  20. }
  21. NCONF_load_bio(conf,bp,&eline);
  22.  
  23. /*读取配置信息并打印*/
  24. v=NCONF_get_section(conf,"CA_default");
  25. num=sk_CONF_VALUE_num(v);
  26. printf("section CA_default :\n");
  27. for(i=0; i<num; i++)
  28. {
  29. one=sk_CONF_VALUE_value(v,i);
  30. printf("%s = %s\n",one->name,one->value);
  31. }
  32.  
  33. /*释放资源*/
  34. BIO_free(bp);
  35.  
  36. return 0;
  37. }

编译

  1. gcc example6.2.c -o example6.2 -L/usr/lib -lssl -lcrypto

运行

程序7:openssl随机数示例

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <openssl/bio.h>
  4. #include <openssl/rand.h>
  5.  
  6. int main()
  7. {
  8. char buf[20];
  9. const char *p;
  10. char out[20],filename[50];
  11. int ret,len;
  12. BIO *print;
  13.  
  14. strcpy(buf,"我的随机数");
  15. RAND_add(buf,20,strlen(buf));
  16. strcpy(buf,"23424d");
  17. RAND_seed(buf,20);
  18.  
  19. while(1)
  20. {
  21. ret=RAND_status(); /*检测熵值*/
  22. if(ret==1)
  23. {
  24. printf("seeded enough!\n");
  25. break;
  26. }
  27. else
  28. {
  29. printf("not enough sedded!\n");
  30. RAND_poll();
  31. }
  32. }
  33.  
  34. p=RAND_file_name(filename,50);
  35. if(p==NULL)
  36. {
  37. printf("can not get rand file\n");
  38. return -1;
  39. }
  40.  
  41. ret=RAND_write_file(p);
  42. len=RAND_load_file(p,1024);
  43. ret=RAND_bytes(out, 20);
  44. if(ret!=1)
  45. {
  46. printf("err.\n");
  47. return -1;
  48. }
  49. print=BIO_new(BIO_s_file());
  50. BIO_set_fp(print,stdout,BIO_NOCLOSE);
  51. BIO_write(print,out,20);
  52. BIO_write(print,"\n",2);
  53.  
  54. /*释放资源*/
  55. BIO_free(print);
  56. RAND_cleanup();
  57.  
  58. return 0;
  59. }

编译

  1. gcc example7.c -o example7 -L/usr/lib -lssl -lcrypto

运行

程序9:openssl错误处理

  1. #include <openssl/err.h>
  2. #include <openssl/bn.h>
  3.  
  4. int mycb(const char *a,size_t b,void *c)
  5. {
  6. printf("my print : %s\n",a);
  7. return 0;
  8. }
  9.  
  10. int main()
  11. {
  12. BIO *berr;
  13. unsigned long err;
  14. const char *file,*data,*efunc,*elib,*ereason,*p;
  15. int line,flags;
  16. char estring[500];
  17. FILE *fp;
  18. /*
  19. ERR_load_crypto_strings();
  20. */
  21. ERR_load_BIO_strings();
  22. ERR_clear_error();
  23. berr=BIO_new(BIO_s_file());
  24. BIO_set_fp(berr,stdout,BIO_NOCLOSE);
  25. BIO_new_file("no.exist","r");
  26. err=ERR_peek_last_error();
  27. err=ERR_peek_last_error_line(&file,&line);
  28. printf("ERR_peek_last_error_line err : %ld,file : %s,line: %d\n",err,file,line);
  29. err=ERR_peek_last_error_line_data(&file,&line,&data,&flags);
  30. printf("ERR_peek_last_error_line_data err: %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
  31. err=ERR_peek_error();
  32. printf("ERR_peek_error err: %ld\n",err);
  33. err=ERR_peek_error_line(&file,&line);
  34. printf("ERR_peek_error_line err : %ld,file : %s,line: %d\n",err,file,line);
  35. err=ERR_peek_error_line_data(&file,&line,&data,&flags);
  36. printf("ERR_peek_error_line_data err : %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
  37. err = ERR_get_error_line_data(&file,&line,&data,&flags);
  38. printf("ERR_get_error_line_data err : %ld,file :%s,line :%d,data :%s\n",err,file,line,data);
  39. if(err!=0)
  40. {
  41. p=ERR_lib_error_string(err);
  42. printf("ERR_lib_error_string : %s\n",p);
  43. }
  44.  
  45. err=ERR_get_error();
  46. if(err!=0)
  47. {
  48. printf("ERR_get_error err : %ld\n",err);
  49. efunc=ERR_func_error_string(err);
  50. printf("err func : %s\n",efunc);
  51. elib=ERR_lib_error_string(err);
  52. printf("err lib : %s\n",efunc);
  53. ereason=ERR_reason_error_string(err);
  54. printf("err reason : %s\n",efunc);
  55. efunc=ERR_func_error_string(err);
  56. printf("err func : %s\n",efunc);
  57. elib=ERR_lib_error_string(err);
  58. printf("err lib : %s\n",efunc);
  59. ereason=ERR_reason_error_string(err);
  60. printf("err reason : %s\n",efunc);
  61. ERR_error_string(err,estring);
  62. printf("ERR_error_string : %s\n",estring);
  63. ERR_error_string_n(err,estring,sizeof(estring));
  64. printf("ERR_error_string_n : %s\n",estring);
  65. }
  66. err=ERR_get_error_line(&file,&line);
  67. printf("err file :%s , err line : %d\n",file,line);
  68. ERR_print_errors(berr);
  69. BIO_new_file("no.exist2","r");
  70. fp=fopen("err.log","w");
  71. ERR_print_errors_fp(fp);
  72. fclose(fp);
  73. BIO_new_file("no.exist3","r");
  74. ERR_print_errors_cb(mycb,NULL);
  75. ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,
  76. line);
  77. ERR_print_errors(berr);
  78. ERR_load_BN_strings();
  79. ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,line);
  80. ERR_print_errors(berr);
  81. ERR_put_error(ERR_LIB_BN,BN_F_BNRAND,BN_R_BIGNUM_TOO_LONG,__FILE__,line);
  82. ERR_set_error_data("set date test!\n",ERR_TXT_STRING);
  83.  
  84. err=ERR_set_mark();
  85. ERR_print_errors(berr);
  86. ERR_free_strings();
  87. BIO_free(berr);
  88. return 0;
  89. }

编译

  1. gcc -g example9.c -o example9 -L/usr/lib -lssl -lcrypto

运行

程序10:openssl证书申请

  1. //example10.1a.c
  1. #include <stdio.h>
  1. #include <string.h>
  2. #include <openssl/x509.h>
  3. #include <openssl/rsa.h>
  4.  
  5. int main()
  6. {
  7. X509_REQ *req;
  8. int ret;
  9. long version;
  10. X509_NAME *name;
  11. EVP_PKEY *pkey;
  12. RSA *rsa;
  13. X509_NAME_ENTRY *entry=NULL;
  14. char bytes[100],mdout[20];
  15. int len,mdlen;
  16. int bits=512;
  17. unsigned long e=RSA_3;
  18. unsigned char *der,*p;
  19. FILE *fp;
  20. const EVP_MD *md;
  21. X509 *x509;
  22. BIO *b;
  23. STACK_OF(X509_EXTENSION) *exts;
  24.  
  25. req=X509_REQ_new();
  26. version=1;
  27. ret=X509_REQ_set_version(req,version);
  28. name=X509_NAME_new();
  29. strcpy(bytes,"openssl");
  30. len=strlen(bytes);
  31.  
  32. entry=X509_NAME_ENTRY_create_by_txt(&entry,"commonName",V_ASN1_UTF8STRING,(unsigned char *)bytes,len);
  33. X509_NAME_add_entry(name,entry,0,-1);
  34.  
  35. strcpy(bytes,"bj");
  36. len=strlen(bytes);
  37.  
  38. entry=X509_NAME_ENTRY_create_by_txt(&entry,"countryName",V_ASN1_UTF8STRING,bytes,len);
  39. X509_NAME_add_entry(name,entry,1,-1);
  40.  
  41. /* subject name */
  42. ret=X509_REQ_set_subject_name(req,name);
  43. /* pub key */
  44. pkey=EVP_PKEY_new();
  45. rsa=RSA_generate_key(bits,e,NULL,NULL);
  46. EVP_PKEY_assign_RSA(pkey,rsa);
  47. ret=X509_REQ_set_pubkey(req,pkey);
  48. /* attribute */
  49. strcpy(bytes,"test");
  50. len=strlen(bytes);
  51.  
  52. ret=X509_REQ_add1_attr_by_txt(req,"organizationName",V_ASN1_UTF8STRING,bytes,len);
  53. strcpy(bytes,"ttt");
  54. len=strlen(bytes);
  55.  
  56. ret=X509_REQ_add1_attr_by_txt(req,"organizationalUnitName",V_ASN1_UTF8STRING,bytes,len);
  57. md=EVP_sha1();
  58. ret=X509_REQ_digest(req,md,mdout,&mdlen);
  59. ret=X509_REQ_sign(req,pkey,md);
  60. if(!ret)
  61. {
  62. printf("sign err!\n");
  63. X509_REQ_free(req);
  64. return -1;
  65. }
  66. /* 写入文件PEM 格式 */
  67. b=BIO_new_file("certreq.txt","w");
  68. PEM_write_bio_X509_REQ(b,req,NULL,NULL);
  69. BIO_free(b);
  70.  
  71. /* DER 编码 */
  72. len=i2d_X509_REQ(req,NULL);
  73. der=malloc(len);
  74. p=der;
  75. len=i2d_X509_REQ(req,&p);
  76. OpenSSL_add_all_algorithms();
  77.  
  78. ret=X509_REQ_verify(req,pkey);
  79. if(ret<0)
  80. {
  81. printf("verify err.\n");
  82. }
  83. fp=fopen("certreq2.txt","wb");
  84. fwrite(der,1,len,fp);
  85. fclose(fp);
  86. free(der);
  87. X509_REQ_free(req);
  88. return 0;
  89. }

编译

  1. gcc -g example10.1a.c -o example10.1a -L/usr/lib -lssl -lcrypto

运行

  1. //example10.1b.c
  1. #include <stdio.h>
  2. #include <string.h>
  1. #include <openssl/pem.h>
  2.  
  3. int main()
  4. {
  5. BIO *in;
  6. X509_REQ *req=NULL,**req2=NULL;
  7. FILE *fp;
  8. unsigned char buf[1024];
  9. char *p;
  10. int len;
  11.  
  12. /*PEM 格式解码*/
  13. in=BIO_new_file("certreq.txt","r");
  14. req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
  15. if(req==NULL)
  16. {
  17. printf("DER解码错误!\n");
  18. }
  19. else
  20. {
  21. printf("DER解码成功!\n");
  22. }
  23.  
  24. /*DER 格式解码*/
  25. fp=fopen("certreq2.txt","r");
  26. fread(buf,1,1024,fp);
  27. fclose(fp);
  28. p=buf;
  29. len=strlen(buf);
  30. req2=(X509_REQ **)malloc(sizeof(X509_REQ *));
  31. d2i_X509_REQ(req2,&p,len);
  32. if(*req2==NULL)
  33. {
  34. printf("DER解码错误!\n");
  35. }
  36. else
  37. {
  38. printf("DER解码成功!\n");
  39. }
  40. X509_REQ_free(*req2);
  41. free(req2);
  42. return 0;
  43. }

编译

  1. gcc -g example10.1b.c -o example10.1b -L/usr/lib -lssl -lcrypto

运行

程序11:openssl CRL(证书撤销列表)示例

  1. #include <stdio.h>
  2. #include <openssl/x509.h>
  3.  
  4. int main()
  5. {
  6. int ret,len;
  7. unsigned char *buf,*p;
  8. unsigned long e=RSA_3;
  9. FILE *fp;
  10. time_t t;
  11. X509_NAME *issuer;
  12. ASN1_TIME *lastUpdate,*nextUpdate,*rvTime;
  13. X509_CRL *crl=NULL;
  14. X509_REVOKED *revoked;
  15. EVP_PKEY *pkey;
  16. ASN1_INTEGER *serial;
  17. RSA *r;
  18. BIGNUM *bne;
  19. BIO *bp;
  20.  
  21. /* 生成密钥*/
  22. bne=BN_new();
  23. ret=BN_set_word(bne,e);
  24. r=RSA_new();
  25. ret=RSA_generate_key_ex(r,1024,bne,NULL);
  26. if(ret!=1)
  27. {
  28. printf("RSA_generate_key_ex err!\n");
  29. return -1;
  30. }
  31. pkey=EVP_PKEY_new();
  32. EVP_PKEY_assign_RSA(pkey,r);
  33.  
  34. /* 设置版本*/
  35. crl=X509_CRL_new();
  36. ret=X509_CRL_set_version(crl,3);
  37.  
  38. /* 设置颁发者*/
  39. issuer=X509_NAME_new();
  40. ret=X509_NAME_add_entry_by_NID(issuer,NID_commonName,V_ASN1_PRINTABLESTRING, "CRL issuer",10,-1,0);
  41. ret=X509_CRL_set_issuer_name(crl,issuer);
  42.  
  43. /* 设置上次发布时间*/
  44. lastUpdate=ASN1_TIME_new();
  45. t=time(NULL);
  46. ASN1_TIME_set(lastUpdate,t);
  47. ret=X509_CRL_set_lastUpdate(crl,lastUpdate);
  48.  
  49. /* 设置下次发布时间*/
  50. nextUpdate=ASN1_TIME_new();
  51. t=time(NULL);
  52. ASN1_TIME_set(nextUpdate,t+1000);
  53. ret=X509_CRL_set_nextUpdate(crl,nextUpdate);
  54.  
  55. /* 添加被撤销证书序列号*/
  56. revoked=X509_REVOKED_new();
  57. serial=ASN1_INTEGER_new();
  58. ret=ASN1_INTEGER_set(serial,1000);
  59. ret=X509_REVOKED_set_serialNumber(revoked,serial);
  60.  
  61. /* 设置吊销日期*/
  62. rvTime=ASN1_TIME_new();
  63. t=time(NULL);
  64. ASN1_TIME_set(rvTime,t+2000);
  65. ret=X509_CRL_set_nextUpdate(crl,rvTime);
  66. ret=X509_REVOKED_set_revocationDate(revoked,rvTime);
  67. ret=X509_CRL_add0_revoked(crl,revoked);
  68.  
  69. /* 排序*/
  70. ret=X509_CRL_sort(crl);
  71.  
  72. /* 签名*/
  73. ret=X509_CRL_sign(crl,pkey,EVP_md5());
  74.  
  75. /* 写入文件*/
  76. bp=BIO_new(BIO_s_file());
  77. BIO_set_fp(bp,stdout,BIO_NOCLOSE);
  78. X509_CRL_print(bp,crl);
  79. len=i2d_X509_CRL(crl,NULL);
  80. buf=malloc(len+10);
  81. p=buf;
  82. len=i2d_X509_CRL(crl,&p);
  83.  
  84. fp=fopen("crl.crl","wb");
  85. fwrite(buf,1,len,fp);
  86. fclose(fp);
  87.  
  88. BIO_free(bp);
  89. X509_CRL_free(crl);
  90. free(buf);
  91. getchar();
  92.  
  93. return 0;
  94. }

编译

  1. gcc -g example11.c -o example11 -L/usr/lib -lssl -lcrypto

运行

程序12:openssl 证书校验示例

  1. /**
  2. * 步骤:
  3. * 1)初始化环境
  4. * a.新建证书存储区X509_STORE_new()
  5. * b.新建证书校验上下文X509_STORE_CTX_new()
  6. *
  7. * 2)导入根证书
  8. * a.读取CA证书,从DER编码格式化为X509结构d2i_X509()
  9. * b.将CA证书导入证书存储区X509_STORE_add_cert()
  10. *
  11. * 3)导入要校验的证书test
  12. * a.读取证书test,从DER编码格式化为X509结构d2i_X509()
  13. * b.在证书校验上下文初始化证书test,X509_STORE_CTX_init()
  14. * c.校验X509_verify_cert
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20.  
  21. #include <openssl/evp.h>
  22. #include <openssl/x509.h>
  23.  
  24. #define CERT_PATH "/root/workspace/caroot"
  25. #define ROOT_CERT "ca.crt"
  26. #define WIN71H "client.crt"
  27. #define WIN71Y "win71y.cer"
  28.  
  29. #define GET_DEFAULT_CA_CERT(str) sprintf(str, "%s/%s", CERT_PATH, ROOT_CERT)
  30. #define GET_CUSTOM_CERT(str, path, name) sprintf(str, "%s/%s", path, name)
  31.  
  32. #define MAX_LEGTH 4096
  33.  
  34. int my_load_cert(unsigned char *str, unsigned long *str_len,
  35. const char *verify_cert, const unsigned int cert_len)
  36. {
  37. FILE *fp;
  38. fp = fopen(verify_cert, "rb");
  39. if ( NULL == fp)
  40. {
  41. fprintf(stderr, "fopen fail\n");
  42. return -1;
  43. }
  44.  
  45. *str_len = fread(str, 1, cert_len, fp);
  46. fclose(fp);
  47. return 0;
  48. }
  49.  
  50. X509 *der_to_x509(const unsigned char *der_str, unsigned int der_str_len)
  51. {
  52. X509 *x509;
  53. x509 = d2i_X509(NULL, &der_str, der_str_len);
  54. if ( NULL == x509 )
  55. {
  56. fprintf(stderr, "d2i_X509 fail\n");
  57.  
  58. return NULL;
  59. }
  60. return x509;
  61. }
  62. int x509_verify()
  63. {
  64. int ret;
  65. char cert[MAX_LEGTH];
  66.  
  67. unsigned char user_der[MAX_LEGTH];
  68. unsigned long user_der_len;
  69. X509 *user = NULL;
  70.  
  71. unsigned char ca_der[MAX_LEGTH];
  72. unsigned long ca_der_len;
  73. X509 *ca = NULL;
  74.  
  75. X509_STORE *ca_store = NULL;
  76. X509_STORE_CTX *ctx = NULL;
  77. STACK_OF(X509) *ca_stack = NULL;
  78.  
  79. /* x509初始化 */
  80. ca_store = X509_STORE_new();
  81. ctx = X509_STORE_CTX_new();
  82.  
  83. /* root ca*/
  84. GET_DEFAULT_CA_CERT(cert);
  85. /* 从文件中读取 */
  86. my_load_cert(ca_der, &ca_der_len, cert, MAX_LEGTH);
  87. /* DER编码转X509结构 */
  88. ca = der_to_x509(ca_der, ca_der_len);
  89. /* 加入证书存储区 */
  90. ret = X509_STORE_add_cert(ca_store, ca);
  91. if ( ret != 1 )
  92. {
  93. fprintf(stderr, "X509_STORE_add_cert fail, ret = %d\n", ret);
  94. goto EXIT;
  95. }
  96.  
  97. /* 需要校验的证书 */
  98. GET_CUSTOM_CERT(cert, CERT_PATH, WIN71H);
  99. my_load_cert(user_der, &user_der_len, cert, MAX_LEGTH);
  100. user = der_to_x509(user_der, user_der_len);
  101.  
  102. ret = X509_STORE_CTX_init(ctx, ca_store, user, ca_stack);
  103. if ( ret != 1 )
  104. {
  105. fprintf(stderr, "X509_STORE_CTX_init fail, ret = %d\n", ret);
  106. goto EXIT;
  107. }
  108.  
  109. //openssl-1.0.1c/crypto/x509/x509_vfy.h
  110. ret = X509_verify_cert(ctx);
  111. if ( ret != 1 )
  112. {
  113. fprintf(stderr, "X509_verify_cert fail, ret = %d, error id = %d, %s\n",
  114. ret, ctx->error, X509_verify_cert_error_string(ctx->error));
  115. goto EXIT;
  116. }
  117. EXIT:
  118. X509_free(user);
  119. X509_free(ca);
  120.  
  121. X509_STORE_CTX_cleanup(ctx);
  122. X509_STORE_CTX_free(ctx);
  123.  
  124. X509_STORE_free(ca_store);
  125.  
  126. return ret == 1 ? 0 : -1;
  127. }
  128.  
  129. int main()
  130. {
  131. OpenSSL_add_all_algorithms();
  132. x509_verify();
  133. return 0;
  134. }

编译

  1. gcc -g example12.c -o example12 -L/usr/local/ssl/lib -lssl -lcrypto -I/usr/local/ssl/include

OpenSSL编程的更多相关文章

  1. Openssl编程--源码分析

    Openssl编程 赵春平 著 Email: forxy@126.com 第一章 基础知识 8 1.1 对称算法 8 1.2 摘要算法 9 1.3 公钥算法 9 1.4 回调函数 11 第二章 ope ...

  2. OPENSSL编程 (secure shell, ssh)

    很好的 OPENSSL编程 教程,名字就叫“OPENSSL编程” 它里面还有很多关于密码学的东西. http://www.pengshuo.me http://www.pengshuo.me/2014 ...

  3. 基于openeuler的openssl编程

    ------------恢复内容开始------------ 一.编译环境 我下载好之后默认安装了openssl,若未安装的可输入以下命令: wget https://www.openssl.org/ ...

  4. OPENSSL编程入门学习

    相关学习资料 http://bbs.pediy.com/showthread.php?t=92649 https://www.openssl.org https://www.google.com.hk ...

  5. 笔记整理——使用openssl编程

    error: openssl 的所有解决方案 (2013/6/22 17:39:00) error: openssl/crypto.h: No such file or directory 解决方案 ...

  6. OPENSSL编程 第二十章 椭圆曲线

    20.1  ECC介绍 椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则.椭圆曲线在如下两个域中定义:Fp域和F2m域. Fp域,素数域,p为素数: F2m域:特征为2的有限域,称之为二 ...

  7. OPENSSL编程起步

    原文链接: http://blog.csdn.net/itmes/article/details/7711076 WINDOWS平台下OPENSSL的编译和安装使用 OPENSSL是开放源代码的,可以 ...

  8. openssl 编程

    背景: 生成私钥.公钥 --> 生成AES-key seed[32], iv[16] --> 公钥加密ASE-key, IV,传给Server --> Server用私钥解密,得到A ...

  9. linux openssl 编程 Client端

    相关配置等请參看上一篇关于server端文章:http://blog.csdn.net/pingd/article/details/47805349 1.Client端源代码: openssl_cli ...

随机推荐

  1. SQL Server占用服务器内存过高

    SQL Server对服务器内存的使用策略是用多少内存就占用多少内存,只用在服务器内存不足时,才会释放一点占用的内存,所以SQL Server 服务器内存往往会占用很高. 查看内存状态: DBCC M ...

  2. django 更新 模板语言

    Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Django的模板语言中按此语法使用:{{ 变量名 ...

  3. selenium+python自动化84-chrome手机wap模式(登录淘宝页面)

    前言 chrome手机wap模式登录淘宝页面,点击验证码无效问题解决. 切换到wap模式,使用TouchActions模块用tap方法触摸 我的环境 chrome 62 chromedriver 2. ...

  4. 3.2_k-近邻算法案例分析

        k-近邻算法案例分析 本案例使用最著名的”鸢尾“数据集,该数据集曾经被Fisher用在经典论文中,目前作为教科书般的数据样本预存在Scikit-learn的工具包中. 读入Iris数据集细节资 ...

  5. 网络层-IP地址

    以下内容是IPv4 IP地址长度32位,Java里面一个int的长度,总共分为5类IP地址 1:分类编址 A类IP地址0开头:           A类有31个位置可以变化,总数是2^31个, [(0 ...

  6. sqlserver导入导出数据库结构及创建用户分配权限

    1.创建用户分配权限 https://www.cnblogs.com/jennyjiang-00/p/5803140.html 2.sqlserver2008导出表结构和表数据 导出表结构   htt ...

  7. 28. 表单css样式定义格式

    form>table>tbody>tr>td{padding:5px;font-size:14px;font-family:"Microsoft YaHei" ...

  8. HTML5 Canvas ( 文字的度量 ) measureText

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. leetcode29

    class Solution { public int divide(int dividend, int divisor) { if (dividend == Integer.MIN_VALUE &a ...

  10. c++变量声明、定义,const变量

    变量声明和定义的主要区别: 声明不分配存储空间,定义分配存储空间. 变量可以声明多次,但只能定义一次(一个变量只能在一个源文件中定义) 声明通常放在头文件(.h)中,定义放在源文件(.cpp)中 变量 ...