/*** @file cert_openssl.c* @brief 利用openssl api处理证书* @author zy* @date 2014-10-11 modify*/
#include <stdio.h>
#include <unistd.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#define CONTEXT_MAX_NUM 7
#define SERIAL_RAND_BITS 64
/**
* 描  述: 获取X509对象
* 参  数: @param[IN] cert_file  证书
* 返回值: X509对象
*/
X509* read_public_cert(const char* cert_file)
{X509 *x509 = NULL;FILE *fp = fopen (cert_file, "r");   if(!fp){printf("read_public_cert, open cert failed!");return NULL; }x509 = PEM_read_X509(fp, NULL, 0, NULL);if(x509 == NULL) {  printf("read_public_cert, get x509 failed!");return NULL;   }return x509;
}
/**
* 描  述: 获取公钥
* 参  数: @param[IN] cert_file  证书
* 返回值: 公钥
*/
EVP_PKEY * read_public_key(const char* cert_file)
{X509 *x509 = NULL;EVP_PKEY *pkey = NULL;FILE *fp = fopen (cert_file, "r");   if(!fp){printf("read_public_key, open cert failed!");return NULL;}x509 = PEM_read_X509(fp, NULL, 0, NULL);if(x509 == NULL) {  printf("read_public_key, get x509 failed!");return NULL;   }fclose(fp);pkey = X509_extract_key(x509);X509_free(x509);if(pkey == NULL){printf("read_public_key, get key failed!");}return pkey;
}
/**
* 描  述: 获取私钥
* 参  数: @param[IN] key_file  证书
* 返回值: 私钥
*/
EVP_PKEY *read_private_key(const char* key_file)
{EVP_PKEY *pkey = NULL;FILE *fp = fopen(key_file, "r");if(!fp){printf("read_private_key, open key failed!");return NULL;}pkey = PEM_read_PrivateKey(fp, NULL, 0, NULL);fclose(fp);if (pkey == NULL){printf("read_private_key, get key failed!");}return pkey;
}
/**
* 描  述: 添加证书内容
* 参  数: @param[IN] name  X509_NAME@param[IN] ctx   使用者信息@param[IN] num   ctx数组长度
* 返回值: 1: 成功 0: 失败
*/
int add_cert_ctx(X509_NAME* name, char* ctx[], int num)
{int i = 0;int max = 0;int item[] = {NID_commonName, NID_countryName,NID_stateOrProvinceName, NID_localityName, NID_organizationName, NID_organizationalUnitName,NID_pkcs9_emailAddress};max = sizeof(item)/sizeof(item[0]);max = max > num ? num : max;for(i=0; i<max; ++i){if(!X509_NAME_add_entry_by_NID(name, item[i], MBSTRING_UTF8, ctx[i], -1, -1, 0)){printf("add_cert_ctx, add entry:%d to %s failed!", item[i], ctx[i]);return 0;}}return 1;
}/**
* 描  述: 创建证书密钥
* 参  数: @param[OUT] pkey  EVP_PKEY@param[IN] bits   密钥长度
* 返回值: 1: 成功 0: 失败
*/
int create_client_key(EVP_PKEY** pkey, int bits)
{RSA *rsa = NULL;EVP_PKEY *pk = NULL;if((pk = EVP_PKEY_new()) == NULL){printf("create_client_key, gen new key failed!");goto err;}rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);if(!EVP_PKEY_assign_RSA(pk, rsa)){printf("create_client_key, assign key failed!");EVP_PKEY_free(pk);goto err;}rsa = NULL;*pkey = pk;return 1;err:return 0;
}
/**
* 描  述: CA签发证书
* 参  数: @param[OUT] x509p      EVP_PKEY@param[OUT] pkey       X509@param[IN] ca_file      CA@param[IN] ca_key_file   CA密钥@param[IN] serial      序列号@param[IN] days        过期时长
* 返回值: 1: 成功 0: 失败
*/
int create_ca_signed_crt(X509** x509p, EVP_PKEY** pkey, const char* ca_file, const char* ca_key_file, const char* user, const int serial, const int days)
{X509* x = NULL;EVP_PKEY* pk = NULL;X509* xca = NULL;EVP_PKEY* xca_key = NULL;X509_NAME* name = NULL;//X509_NAME *tname = NULL;//char buf[256] = {0};char* ctx[] = {(char*)user, "bb", "cc", "dd", "ee", "ff", "ff@sf.com"};if(!create_client_key(&pk, 2048)){printf("create_ca_signed_crt, gen key failed!");goto err;}if((x = X509_new()) == NULL){printf("create_ca_signed_crt, gen x509 failed!");goto err;}xca = read_public_cert(ca_file);xca_key = read_private_key(ca_key_file);if(!X509_check_private_key(xca, xca_key)){printf("create_ca_signed_crt, check ca %s and key %s failed!", ca_file, ca_key_file);goto err;}if(!X509_set_issuer_name(x, X509_get_subject_name(xca))){printf("create_ca_signed_crt, set issuer failed!");goto err;}ASN1_INTEGER_set(X509_get_serialNumber(x), serial);if(X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL){printf("create_ca_signed_crt, set cert begin time failed!");goto err;}if(X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days) == NULL){printf("create_ca_signed_crt, set cert expired time failed!");goto err;}if(!X509_set_pubkey(x, pk)){printf("create_ca_signed_crt, set pubkey failed!");goto err;}//tname = X509_get_subject_name(xca);//X509_NAME_get_text_by_NID(tname, NID_localityName, buf, 256);//printf("city: %s\n", buf);name = X509_get_subject_name(x);if(!add_cert_ctx(name, ctx, CONTEXT_MAX_NUM)){printf("create_ca_signed_crt, add entry failed!");goto err;}if(!X509_sign(x, xca_key, EVP_sha1())){printf("create_ca_signed_crt, sign cert failed!");goto err;}*pkey = pk;*x509p = x;return 1;
err:if(x)X509_free(x);if(pk)EVP_PKEY_free(pk);return 0;
}
/**
* 描  述: 创建P12证书
* 参  数: @param[IN] p12_file     p12@param[IN] p12_passwd   p12密码@param[IN] ca_file      CA@param[IN] ca_key_file   CA密钥@param[IN] serial      序列号@param[IN] days        过期时长
* 返回值: 1: 成功 0: 失败
*/
int create_p12_cert(char* p12_file, char* p12_passwd, const char* ca_file, const char* ca_key_file, const char* user, const int serial, const int days)
{int ret = 0;PKCS12* p12 = NULL;X509* cert = NULL;EVP_PKEY* pkey = NULL;FILE *fp = NULL;BIO *mem = NULL;char *mem_out = NULL;long len = 0;SSLeay_add_all_algorithms();if(!create_ca_signed_crt(&cert, &pkey, ca_file, ca_key_file, user, serial, days)){printf("create_p12_cert, create signed cert failed!");goto err;}p12 = PKCS12_create(p12_passwd, NULL, pkey, cert, NULL, 0,0,0,0,0);if(!p12){printf("create_p12_cert, create p12 object failed!");goto err;}/*fp = fopen(p12_file, "wb");if(!fp){printf("create_p12_cert, open/create p12 file failed!");goto err;}if(!i2d_PKCS12_fp(fp, p12)){printf("create_p12_cert, put p12 file failed!");goto err;}*/fp = fopen(p12_file, "wb");if(!fp){printf("create_p12_cert, open/create p12 file failed!");goto err;}mem = BIO_new(BIO_s_mem());if(!mem){printf("create_p12_cert, BIO_new failed!");goto err;}i2d_PKCS12_bio(mem, p12);len = BIO_get_mem_data(mem, &mem_out);fwrite(mem_out, sizeof(char), len, fp);ret = 1;
err:if(cert)X509_free(cert);if(pkey)EVP_PKEY_free(pkey);if (p12)PKCS12_free(p12);if (mem)BIO_free(mem);if(fp)fclose(fp);EVP_cleanup();return ret;
}
//openssl smime -sign -in unsign.mc -out signed.mc -signer ssl.crt -inkey ssl.key -certfile server.crt -outform der -nodetach
int sign_mobile_config(const char *inmc, int inlen, char **outmc, int *outlen,char *certfile, char *signerfile, char *keyfile)
{X509 *signer = NULL;EVP_PKEY *key = NULL;PKCS7 *p7 = NULL;X509 *cert = NULL;BIO *in = NULL;BIO *out = NULL;STACK_OF(X509) * other = NULL;int mclen = 0;char *mc = NULL;char *tmp = NULL;SSLeay_add_all_algorithms();// in in = BIO_new_mem_buf((char*)inmc, inlen); // BIO_writeif (!in){return -1;}cert = read_public_cert(certfile);other = sk_X509_new_null();sk_X509_push(other, cert);signer = read_public_cert(signerfile);key = read_private_key(keyfile);if (!X509_check_private_key(signer, key)){printf("x509 check failed!\n");return -1;}p7 = PKCS7_sign(signer, key, other, in, 0);if (!p7)goto end;// outout = BIO_new(BIO_s_mem());i2d_PKCS7_bio(out, p7);mclen = BIO_get_mem_data(out, &tmp);// BIO_readmc = (char*)malloc(mclen);memcpy(mc, tmp, mclen);*outmc = mc;*outlen = mclen;end:sk_X509_pop_free(other, X509_free);X509_free(signer);EVP_PKEY_free(key);PKCS7_free(p7);BIO_free(in);BIO_free_all(out);return 0;
}int main()
{create_p12_cert("/root/out.p12", "1234", "/root/server_mdm.crt", "/root/server_mdm.key", "test", 0, 3650);return 0;
}
gcc -o test cert_openssl.c -L. -lcrypto#include<stdio.h> #include<stdlib.h>#include<string.h>#include<openssl/rsa.h>#include<openssl/pem.h>#include<openssl/err.h>void hexprint(char *str,int len){int i=0;for(i=0;i<len;i++){printf("%s%02x%s",((i%16==0?"|":"")),*((unsigned char*)str+i),(((i+1)%16==0)?"|\n":" "));}if(i%16!=0)printf("|\n");}static int do_operation(RSA* rsa_ctx,char *instr,char* path_key,int inlen,char** outstr,int type){if(rsa_ctx == NULL || instr == NULL || path_key == NULL){perror("input elems error,please check them!");return -1;}int rsa_len,num;rsa_len=RSA_size(rsa_ctx);*outstr=(unsigned char *)malloc(rsa_len+1);memset(*outstr,0,rsa_len+1);switch(type){case 1: //pub encif(inlen == 0){perror("input str len is zero!");goto err;}num = RSA_public_encrypt(inlen,(unsigned char *)instr,(unsigned char*)*outstr,rsa_ctx,RSA_PKCS1_OAEP_PADDING);break;case 2: //prv decnum = RSA_private_decrypt(inlen,(unsigned char *)instr,(unsigned char*)*outstr,rsa_ctx,RSA_PKCS1_OAEP_PADDING);        default:break;}if(num == -1){printf("Got error on enc/dec!\n");err:free(*outstr);*outstr = NULL;num = -1;}return num;}int rsa_pub_encrypt(char *str,char *path_key,char** outstr){RSA *p_rsa;FILE *file;int flen,rsa_len,num;if((file=fopen(path_key,"r"))==NULL){perror("open key file error");return -1; } #ifdef RSAPUBKEYif((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){#elseif((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){#endifERR_print_errors_fp(stdout);return -1;} num = do_operation(p_rsa,str,path_key,strlen(str),outstr,1);RSA_free(p_rsa);fclose(file);return num;}int rsa_prv_decrypt(char *str,char *path_key,int inlen,char** outstr){    RSA *p_rsa;FILE *file;int rsa_len,num;if((file=fopen(path_key,"r"))==NULL){perror("open key file error");return -1;}if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){ERR_print_errors_fp(stdout);return -1;}    num = do_operation(p_rsa,str,path_key,inlen,outstr,2);RSA_free(p_rsa);fclose(file);return num;}int main(int argc,char** argv){ char *ptr_en,*ptr_de;int len;printf("source is    :%s\n",argv[1]);len=rsa_pub_encrypt(argv[1],argv[2],&ptr_en);printf("pubkey encrypt:\n");hexprint(ptr_en,len);rsa_prv_decrypt(ptr_en,argv[3],len,&ptr_de);printf("prvkey decrypt:%s\n",ptr_de==NULL?"NULL":ptr_de);if(ptr_en!=NULL){free(ptr_en);} if(ptr_de!=NULL){free(ptr_de);} return 0;}

OpenSSL API相关推荐

  1. 【转】使用 OpenSSL API 进行安全编程 - 创建基本的安全连接和非安全连接

    Table of Contents 先决条件 什么是 SSL? 什么是 OpenSSL? 您需要什么 头文件和初始化 建立非安全连接 打开连接 与服务器进行通信 关闭连接 建立安全连接 为安全连接进行 ...

  2. OpenSSL API 签发证书

    /**  * @file cert_openssl.c  * @brief 利用openssl api处理证书  * @author zy  * @date 2014-10-11 modify  */ ...

  3. OpenSSL API: SSL对象和SSL_CTX对象的使用

    OpenSSL 库的核心数据结构是SSL对象和SSL_CTX对象, 两种数据结构都是private私有结构体. OpenSSL的决大部分API函数都在围绕这两种数据结构体完成TLS握手和数据加解密工作 ...

  4. windows qt 使用openssl API

    1.下载安装openssl http://dl.pconline.com.cn/download/355862-1.html 版本: OpenSSL(Win32) 1.0.1g 2.配置QT项目文件, ...

  5. 调用openssl api函数C代码生成证书

    概述 因工作需要用到很多新证书,但是我想更灵活处理证书,而不是用openssl命令行生成证书.网上一堆的命令行操作,我找了很久没有发现用代码生成证书的. 基于此,本人利用端午放假,花了一整天的时间,翻 ...

  6. linux c openssl rsa 加解密

    1.PEM私钥文件格式 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 生成该密钥的Linux命令:OpenSSL>g ...

  7. Linux C/C++ Openssl RSA Encrypt/Decrypt(加密/解密) 简单示例教程

    PEM文件有以下格式 1.PEM私钥文件格式 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 生成该密钥的Linux命令 : ...

  8. 密码学专题 OpenSSL专题

    OpenSSL总体架构 软件包分为三个主要的功能部分:密码算法库 . SSL协议库及应用程序 MacOS,MS,OS/2及 VMS这几个目录,包含了在不同的 平台编译时的环境变量配置文件,在安装编译完 ...

  9. Openssl证书管理

    目录 [隐藏] 1 已整理部分 1.1 为CA创建一个RSA私钥 1.2 python编程实现Demon 1.3 为客户创建一个RSA私钥,并使用CA证书来对其签署 1.4 撤销一个客户证书 1.5  ...

最新文章

  1. 人工智能芯片支持超低功耗器件的推理
  2. 对AFNetworking的简单封装
  3. opencv2中访问像素的简单方法-自定义一个宏CV_MAT_ELEM2
  4. 广播等风暴的解决办法
  5. 嵌入式系统UBOOT
  6. shell命令之---sed
  7. PetShop4.0--转载
  8. Python学习入门1:Python 新手入门引导
  9. TreeSet—————我们认知的集合
  10. Android App混合开发
  11. SiT3808:1 -80MHz 单端压控振荡器VCXO
  12. 使用OpenCV将一个三角形图形扭曲到另一个三角形
  13. 伦敦 quant_伦敦统一用户组(LUUG)见面v1.0
  14. Forethought Future Cup - Elimination Round G. Zoning Restrictions 最大流(最小割)
  15. 白塞尔公式_如何设计像乌塞尔这样的800人的婚礼
  16. 大米新闻微信小程序和Springboot新闻管理系统项目源码
  17. Mysql学习代码笔记
  18. AWS - Auto Scaling 介绍
  19. 微信订阅号之客服消息接口回复
  20. Tableau中的表计算

热门文章

  1. 苹果cmsv10自适应模板自带后台系统原创多功能漂亮主题
  2. 同期两篇Nature:运行温度高于1K的量子计算平台!
  3. php 混合开发框架,Spiral: 性能卓越的PHP/Golang混合开发框架
  4. 浅谈常用的几种web攻击方式以及解决办法
  5. mpls通过BGP实现互通
  6. fastboot 详解
  7. mongoTemplate使用group函数进行分组和统计
  8. Shell脚本(五)-脚本中运算符号及命令
  9. oracle spatial java 类库,[ Oracle Spatial 系列 ] 之一 SDO_Geometry详细说明(ZZ)
  10. 【Springcloud】<微服务>微服务架构设计理念