赞
踩
目录
关于openssl的部署比较简单,在之前wifi功能移植中有过说明,或者网上大把详细步骤
命令行的方式生成证书: https://blog.csdn.net/gengxiaoming7/article/details/78505107
参考文章:https://blog.csdn.net/qq_30667875/article/details/105427943
我的具体实现
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<openssl/rsa.h>
- #include <openssl/pem.h>
- #include <openssl/err.h>
- #include <fstream>
-
- using namespace std;
-
- #define LOG_INFO(fmt,args...) ({printf("info: %s(%d) %s:",__FILE__, __LINE__, __func__);printf(fmt"\r\n" ,##args);})
- #define LOG_ERROR(fmt,args...) ({printf("error: %s(%d) %s:",__FILE__, __LINE__, __func__);printf(fmt"\r\n" ,##args);})
-
-
- #define RSA_OPENSSLKEY "./rsa_private_key.pem"
- #define RSA_PUBLICKEY "./rsa_public_key.pem"
-
- #define KEY_LENGTH 2048
-
- //生成秘钥
- void GenerateRSAKey(std::string & out_pub_key, std::string & out_pri_key);
-
- //传入秘钥内容进行加解密
- std::string RsaPriEncrypt(const std::string &clear_text, std::string &pri_key);
- std::string RsaPubDecrypt(const std::string & cipher_text, const std::string & pub_key);
-
-
- //通过读秘钥文件的方式进行加解密
- std::string RsaPriEncryptFile(const std::string &clear_text);
- std::string RsaPubDecryptFile(const std::string & cipher_text);
-
-
- int main(int argc, char* argv[])
- {
- char *p_str="qaq1234567abcdef";
-
- std::string encrypt_text;
- std::string decrypt_text;
-
- std::string encryptFile_text;
- std::string decryptFile_text;
-
- std::string pub_key;
- std::string pri_key;
- GenerateRSAKey(pub_key, pri_key);
- LOG_INFO("public key:\n");
- LOG_INFO("%s\n", pub_key.c_str());
- LOG_INFO("private key:\n");
- LOG_INFO("%s\n", pri_key.c_str());
-
-
- // 直接使用秘钥信息的方式加解密
- // 私钥加密-公钥解密
- encrypt_text = RsaPriEncrypt(p_str, pri_key);
- LOG_INFO("encrypt: len=%d\n", encrypt_text.length());
- LOG_INFO("decrypt: %s\n", encrypt_text.c_str());
- decrypt_text = RsaPubDecrypt(encrypt_text, pub_key);
- LOG_INFO("decrypt: len=%d\n", decrypt_text.length());
- LOG_INFO("decrypt: %s\n", decrypt_text.c_str());
-
- printf("==================================\n");
-
- // 通过读秘钥文件的方式加解密
- encryptFile_text = RsaPriEncryptFile(p_str);
- LOG_INFO("encrypt: len=%d\n", encryptFile_text.length());
- LOG_INFO("encrypt: %s\n", encryptFile_text.c_str());
- decryptFile_text = RsaPubDecryptFile(encryptFile_text);
- LOG_INFO("decrypt: len=%d\n", decryptFile_text.length());
- LOG_INFO("decrypt: %s\n", decryptFile_text.c_str());
-
-
-
- return 0;
- }
-
- void GenerateRSAKey(std::string & out_pub_key, std::string & out_pri_key)
- {
- size_t pri_len = 0; // 私钥长度
- size_t pub_len = 0; // 公钥长度
- char *pri_key = nullptr; // 私钥
- char *pub_key = nullptr; // 公钥
-
- // 生成密钥对
- RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
-
- BIO *pri = BIO_new(BIO_s_mem());
- BIO *pub = BIO_new(BIO_s_mem());
-
- // 生成私钥
- PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
- // 注意------生成第1种格式的公钥
- //PEM_write_bio_RSAPublicKey(pub, keypair);
- // 注意------生成第2种格式的公钥(此处代码中使用这种)
- PEM_write_bio_RSA_PUBKEY(pub, keypair);
-
- // 获取长度
- pri_len = BIO_pending(pri);
- pub_len = BIO_pending(pub);
-
- // 密钥对读取到字符串
- pri_key = (char *)malloc(pri_len + 1);
- pub_key = (char *)malloc(pub_len + 1);
-
- BIO_read(pri, pri_key, pri_len);
- BIO_read(pub, pub_key, pub_len);
-
- pri_key[pri_len] = '\0';
- pub_key[pub_len] = '\0';
-
- out_pub_key = pub_key;
- out_pri_key = pri_key;
-
- // 将公钥写入文件
- std::ofstream pub_file(RSA_PUBLICKEY, std::ios::out);
- if (!pub_file.is_open())
- {
- perror("pub key file open fail:");
- goto ERROR;
- return;
- }
- pub_file << pub_key;
- pub_file.close();
-
- // 将私钥写入文件
- std::ofstream pri_file(RSA_OPENSSLKEY, std::ios::out);
- if (!pri_file.is_open())
- {
- perror("pri key file open fail:");
- goto ERROR;
- return;
- }
- pri_file << pri_key;
- pri_file.close();
-
- ERROR:
- // 释放内存
- RSA_free(keypair);
- BIO_free_all(pub);
- BIO_free_all(pri);
-
- free(pri_key);
- free(pub_key);
- }
-
- std::string RsaPriEncrypt(const std::string &clear_text, std::string &pri_key)
- {
- std::string encrypt_text;
- BIO *keybio = BIO_new_mem_buf((unsigned char *)pri_key.c_str(), -1);
- RSA* rsa = RSA_new();
- rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
- if (!rsa)
- {
- BIO_free_all(keybio);
- return std::string("");
- }
-
- // 获取RSA单次可以处理的数据的最大长度
- int len = RSA_size(rsa);
-
- // 申请内存:存贮加密后的密文数据
- char *text = new char[len + 1];
- memset(text, 0, len + 1);
-
- // 对数据进行私钥加密(返回值是加密后数据的长度)
- int ret = RSA_private_encrypt(clear_text.length(), (const unsigned char*)clear_text.c_str(), (unsigned char*)text, rsa, RSA_PKCS1_PADDING);
- if (ret >= 0) {
- encrypt_text = std::string(text, ret);
- }
-
- // 释放内存
- delete text;
- BIO_free_all(keybio);
- RSA_free(rsa);
-
- return encrypt_text;
- }
-
- std::string RsaPubDecrypt(const std::string & cipher_text, const std::string & pub_key)
- {
- std::string decrypt_text;
- BIO *keybio = BIO_new_mem_buf((unsigned char *)pub_key.c_str(), -1);
- RSA *rsa = RSA_new();
-
- // 注意--------使用第1种格式的公钥进行解密
- //rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
- // 注意--------使用第2种格式的公钥进行解密(我们使用这种格式作为示例)
- rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
- if (!rsa)
- {
- unsigned long err = ERR_get_error(); //获取错误号
- char err_msg[1024] = { 0 };
- ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因
- printf("err msg: err:%ld, msg:%s\n", err, err_msg);
- BIO_free_all(keybio);
- return decrypt_text;
- }
-
- int len = RSA_size(rsa);
- char *text = new char[len + 1];
- memset(text, 0, len + 1);
- // 对密文进行解密
- int ret = RSA_public_decrypt(cipher_text.length(), (const unsigned char*)cipher_text.c_str(), (unsigned char*)text, rsa, RSA_PKCS1_PADDING);
- if (ret >= 0) {
- decrypt_text.append(std::string(text, ret));
- }
-
- // 释放内存
- delete text;
- BIO_free_all(keybio);
- RSA_free(rsa);
-
- return decrypt_text;
- }
-
- std::string RsaPriEncryptFile(const std::string &clear_text)
- {
- std::string encrypt_text;
- RSA *prikey = RSA_new();
- BIO *priio;
-
- priio = BIO_new_file(RSA_OPENSSLKEY, "rb");
- prikey = PEM_read_bio_RSAPrivateKey(priio, &prikey, NULL, NULL);
- if (!prikey)
- {
- BIO_free(priio);
- return std::string("");
- }
- int len = RSA_size(prikey);
- char *text = new char[len + 1];
- memset(text, 0, len + 1);
-
- int ret = RSA_private_encrypt(clear_text.length(), (const unsigned char*)clear_text.c_str(), (unsigned char*)text, prikey, RSA_PKCS1_PADDING);
- if (ret >= 0) {
- encrypt_text = std::string(text, ret);
- }
- delete text;
- RSA_free(prikey);
- BIO_free(priio);
-
- return encrypt_text;
- }
-
- std::string RsaPubDecryptFile(const std::string & cipher_text)
- {
- std::string decrypt_text;
- RSA *pubkey = RSA_new();
- BIO *pubio;
- pubio = BIO_new_file(RSA_PUBLICKEY, "rb");
- pubkey = PEM_read_bio_RSA_PUBKEY(pubio, &pubkey, NULL, NULL);
- if (!pubkey)
- {
- unsigned long err = ERR_get_error(); //获取错误号
- char err_msg[1024] = { 0 };
- ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因
- printf("err msg: err:%ld, msg:%s\n", err, err_msg);
- BIO_free(pubio);
- return decrypt_text;
- }
-
- int len = RSA_size(pubkey);
- char *text = new char[len + 1];
- memset(text, 0, len + 1);
-
- int ret = RSA_public_decrypt(cipher_text.length(), (const unsigned char*)cipher_text.c_str(), (unsigned char*)text, pubkey, RSA_PKCS1_PADDING);
- if (ret >= 0) {
- decrypt_text.append(std::string(text, ret));
- }
-
- delete text;
- RSA_free(pubkey);
- BIO_free(pubio);
-
- return decrypt_text;
- }
记得编译时加上 -lssl -lcrypto
命令行方式:
message.sign:签名文件
source_ile:目标文件
sha1:摘要算法 使用openssl dgst - 可以看到支持的列表
使用私钥对升级包进行签名
openssl dgst -sha1 -out message.sign -sign rsa_private_key.pem source_file
使用公钥验证签名
openssl dgst -sha1 -verify rsa_public_key.pem -signature message.sign source_file
代码实现
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <openssl/rsa.h>
- #include <openssl/pem.h>
- #include <openssl/err.h>
- #include <openssl/evp.h>
-
- #define SIGN_PATH "./.message.sign" //签名文件
- #define SOURCE_PATH "./source_file" //源文件
-
- #define PUBLIC_KEY_PASH "./pub_key.pem" //公钥
-
- static EVP_PKEY *PEM_read_PublicKey(FILE *fp)
- {
- BIO *b;
- EVP_PKEY *ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL)
- {
- //PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = PEM_read_bio_PUBKEY(b, NULL, NULL, NULL);
- BIO_free(b);
- return(ret);
- }
-
- static EVP_PKEY* Read_PublicKey(char* p_KeyPath)
- {
- FILE *fp = NULL;
- char szKeyPath[1024];
- EVP_PKEY *pubRsa = NULL;
-
- /* 打开密钥文件 */
- if (NULL == (fp = fopen(p_KeyPath, "r")))
- {
- return NULL;
- }
- /* 获取私密钥 */
- pubRsa = PEM_read_PublicKey(fp);
- if (NULL == pubRsa)
- {
- fclose(fp);
- return NULL;
- }
- fclose(fp);
-
- return pubRsa;
- }
-
- int VerifyUpgrade(char *sign_data, int sign_len)
- {
- printf("sign_len = %d\n", sign_len);
-
- int nRet = 0;
- EVP_PKEY *pKey;
- EVP_MD_CTX* pMdCtx = NULL;
- EVP_PKEY_CTX* pKeyCtx = NULL;
-
- /*初始化验签函数*/
- pKey = Read_PublicKey(PUBLIC_KEY_PASH);
- if (!pKey)
- {
- printf("Read_PublicKey failed!\n");
- return -1;
- }
-
- pMdCtx = EVP_MD_CTX_create();
- if (NULL == pMdCtx)
- {
- printf("EVP_MD_CTX_create failed!\n");
- EVP_PKEY_free(pKey);
- pKey = NULL;
- return -1;
- }
-
- nRet = EVP_DigestVerifyInit(pMdCtx, &pKeyCtx, EVP_sha256(), NULL, pKey);
- if (nRet <= 0)
- {
- printf("EVP_DigestVerifyInit failed!\n");
- EVP_PKEY_free(pKey);
- pKey = NULL;
- EVP_MD_CTX_destroy(pMdCtx);
- pMdCtx = NULL;
- return -1;
- }
-
- FILE *fp = NULL;
- char p_pBuf[512];
- fp = fopen(SOURCE_PATH, "r");
- while (feof(fp) == 0)
- {
- int i = fread(p_pBuf, 1, 512, fp);
- EVP_DigestVerifyUpdate(pMdCtx, p_pBuf, i);
- }
-
-
- /*验签*/
- nRet = EVP_DigestVerifyFinal(pMdCtx, (unsigned char *)sign_data, sign_len);
- if (nRet <= 0)
- {
- printf("EVP_DigestVerifyFinal failed !!! nRet = %d \n", nRet);
- EVP_PKEY_free(pKey);
- pKey = NULL;
- EVP_MD_CTX_destroy(pMdCtx);
- pMdCtx = NULL;
- fclose(fp);
- printf("========================= Verify Failed ========================\n");
- return -1;
- }
- fclose(fp);
-
- printf("========================= Verify Success ========================\n");
-
- return 0;
- }
-
- int main()
- {
- int sign_len = 0;
- char *p_sign_data = NULL;
-
- struct stat statbuf;
- stat(SIGN_PATH, &statbuf);
- sign_len = statbuf.st_size;
-
- p_sign_data = (char *)malloc(sign_len);
- memset(p_sign_data, 0, sign_len);
- FILE *sign_fp = fopen(SIGN_PATH, "r");
- if (sign_fp)
- {
- fread(p_sign_data, 1, sign_len, sign_fp);
- }
-
- VerifyUpgrade(p_sign_data, sign_len);
-
- free(p_sign_data);
-
- return 0;
- }
命令行方式:
1、ecb
echo -n "AA:BB:CC:11:22:33" | openssl enc -aes-128-ecb -K 78346c3932774542754d32656e345273 | xxd -p -c 64
AA:BB:CC:11:22:33 要加密的字符串
xxd让加密后的内容以十六进制的方式显示,方便查看
2、cbc
echo -n "test" | openssl enc -aes-128-cbc -K 69249e45dd8f1088c6ce8ec74b027035 -iv 69249e45dd8f1088c6ce8ec74b027035 | xxd
代码实现:(这里实现的是cbc,ecb大同小异)
命令行指定的key和iv是十六进制数,为了能跟命令行的输出结果一致,这里简单赋了一下值
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <openssl/evp.h>
- #include <openssl/aes.h>
-
-
- static unsigned char sAesIV[] = "69249e45dd8f1088c6ce8ec74b027035";
- static unsigned char sAesKey[] = "69249e45dd8f1088c6ce8ec74b027035";
-
- int AES_ENC(char *_InData, int InLen, char *OutData, int *OutLen)
- {
- unsigned char key[16] = {}, iv[16] = { 0 };
- key[0] = 0x69;
- key[1] = 0x24;
- key[2] = 0x9e;
- key[3] = 0x45;
- key[4] = 0xdd;
- key[5] = 0x8f;
- key[6] = 0x10;
- key[7] = 0x88;
- key[8] = 0xc6;
- key[9] = 0xce;
- key[10] = 0x8e;
- key[11] = 0xc7;
- key[12] = 0x4b;
- key[13] = 0x02;
- key[14] = 0x70;
- key[15] = 0x35;
-
- iv[0] = 0x69;
- iv[1] = 0x24;
- iv[2] = 0x9e;
- iv[3] = 0x45;
- iv[4] = 0xdd;
- iv[5] = 0x8f;
- iv[6] = 0x10;
- iv[7] = 0x88;
- iv[8] = 0xc6;
- iv[9] = 0xce;
- iv[10] = 0x8e;
- iv[11] = 0xc7;
- iv[12] = 0x4b;
- iv[13] = 0x02;
- iv[14] = 0x70;
- iv[15] = 0x35;
-
-
- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
- EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);
-
- int len = 0;
- EVP_CipherUpdate(ctx, (unsigned char*)OutData, &len, (unsigned char*)_InData, InLen);
- *OutLen = len;
- EVP_CipherFinal_ex(ctx, (unsigned char*)OutData + len, &len);
- *OutLen += len;
- EVP_CIPHER_CTX_free(ctx);
-
- return 0;
- }
-
- int AES_DEC(char *_InData, int InLen, char *OutData, int *OutLen)
- {
- unsigned char key[16] = {}, iv[16] = { 0 };
- key[0] = 0x69;
- key[1] = 0x24;
- key[2] = 0x9e;
- key[3] = 0x45;
- key[4] = 0xdd;
- key[5] = 0x8f;
- key[6] = 0x10;
- key[7] = 0x88;
- key[8] = 0xc6;
- key[9] = 0xce;
- key[10] = 0x8e;
- key[11] = 0xc7;
- key[12] = 0x4b;
- key[13] = 0x02;
- key[14] = 0x70;
- key[15] = 0x35;
-
- iv[0] = 0x69;
- iv[1] = 0x24;
- iv[2] = 0x9e;
- iv[3] = 0x45;
- iv[4] = 0xdd;
- iv[5] = 0x8f;
- iv[6] = 0x10;
- iv[7] = 0x88;
- iv[8] = 0xc6;
- iv[9] = 0xce;
- iv[10] = 0x8e;
- iv[11] = 0xc7;
- iv[12] = 0x4b;
- iv[13] = 0x02;
- iv[14] = 0x70;
- iv[15] = 0x35;
-
- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
- EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 0);
-
- int len = 0;
- EVP_CipherUpdate(ctx, (unsigned char*)OutData, &len, (unsigned char*)_InData, InLen);
- *OutLen = len;
- EVP_CipherFinal_ex(ctx, (unsigned char*)OutData + len, &len);
- *OutLen += len;
- EVP_CIPHER_CTX_free(ctx);
-
- return 0;
-
- }
-
- int main()
- {
- char Source[128] = "test";
- char EncData[128] = {};
- char DecData[128] = {};
- int EncLen = 0;
- int DecLen = 0;
-
- AES_ENC(Source, (int)strlen(Source), EncData, &EncLen);
- for (int i = 0; i < EncLen; ++i)
- printf("%02x ", EncData[i]);
- printf("\n");
-
- AES_DEC(EncData, (int)strlen(EncData), DecData, &DecLen);
- for (int i = 0; i < DecLen; ++i)
- printf("%x ", DecData[i]);
- printf("\n");
-
- return 0;
- }
注意:
openssl默认是PKCS7
填充的数据,AES-128
, AES-192
, AES-256
的数据块长度分别为 128/8=16bytes
, 192/8=24bytes
, 256/8=32bytes。
当我们拿到一串PKCS7
填充的数据时,取其最后一个字符paddingChar
,此字符的ASCII
码的十进制ord(paddingChar)
即为填充的数据长度paddingSize
,读取真实数据时去掉填充长度即可得到原始的数据。
命令行输出结果
代码输出结果
- #include <stdio.h>
- #include <string.h>
-
- #include "openssl/ssl.h"
- #include "openssl/crypto.h"
- #include "openssl/conf.h"
- #include "openssl/x509v3.h"
- #include "openssl/err.h"
- #include "openssl/engine.h"
- #include "openssl/rsa.h"
-
- //#define BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
- //#define PADDING_BUF(LEN) (LEN %4 == 0)?(LEN + 4):((LEN + 0x03) &(~0x03))
- #define SERVER_CIPHERS "ALL"
- #define CLIENT_CIPHERS "ALL:!EXPORT:!LOW"
-
- #define BUF_LEN (128)
- #define BUF_BUF (BUF_LEN + 4)
-
- #define CUSTOM_CERT_KEY_PATH "./custom_key.pem"
- #define CUSTOM_CERT_REQ_PATH "./certreq.pem"
-
- #define CUSTOM_CERT_TEMP_PATH "./custom_cert_temp.pem"
-
- typedef struct _certificate_params_t
- {
- char commonName[BUF_BUF];
- char country[BUF_BUF];
- char stateOrProvince[BUF_BUF];
- char locality[BUF_BUF];
- char organization[BUF_BUF];
- char organizationUnit[BUF_BUF];
- }certificate_params_t;
-
- //创建证书请求文件pem
- static int create_cret(certificate_params_t *param);
-
- static int check_certs_availability(const char *p_ciphers, const char *p_ca, const char *p_cert,const char *p_private_key);
-
- int main(int argc, char *argv[])
- {
- certificate_params_t param = {};
-
- memcpy(param.country,"SZ" , BUF_LEN);
- memcpy(param.stateOrProvince,"GD", BUF_LEN);
- memcpy(param.locality,"NS", BUF_LEN);
- memcpy(param.organization,"MYSELF", BUF_LEN);
- memcpy(param.organizationUnit,"MY" , BUF_LEN);
- memcpy(param.commonName,"SS", BUF_LEN);
-
- create_cret(¶m);
-
-
-
- return 0;
-
- //TODO
- //write file
-
- //检查证书是否合法
- check_certs_availability(SERVER_CIPHERS, NULL, CUSTOM_CERT_TEMP_PATH, CUSTOM_CERT_KEY_PATH);//check证书有误
-
-
- return 0;
- }
-
- static int _name_entry_create_by_txt(X509_NAME* name,X509_NAME_ENTRY *entry,const char *field,const char* pNameStr,int nameLen)
- {
- if(0==nameLen || nameLen> 128 || NULL==name || NULL==pNameStr)
- return -1;
- char bytes[128]={0};
- memset(&bytes,0,sizeof(bytes));
- memcpy(bytes, pNameStr,sizeof(bytes) );
- int len = strlen(bytes);
- entry = X509_NAME_ENTRY_create_by_txt(&entry, field, V_ASN1_UTF8STRING, (unsigned char*)bytes, len);
- X509_NAME_add_entry(name, entry, 0, -1);
-
- return 0;
- }
-
- static int create_cret(certificate_params_t *param)
- {
- if(NULL == param)
- return -1;
-
- X509_NAME_ENTRY* entry = NULL;
- const EVP_MD* md;
- BIO* b;
- unsigned long e = RSA_3;
- char mdout[20];
- int mdlen;
- int bits = 1024;//512;
- int ret = 0;
-
- X509_REQ*req = X509_REQ_new();
- long version = 1;
- ret = X509_REQ_set_version(req, version);
- X509_NAME* name = X509_NAME_new();
-
- //Common Name (e.g. server FQDN or YOUR name) CN
- if( 0!=_name_entry_create_by_txt( name, entry, "commonName", param->commonName, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt commonName err!!! \n",__FUNCTION__,__LINE__);
- return -2;
- }
-
- //Country Name (2 letter code) C
- if( 0!=_name_entry_create_by_txt( name, entry, "countryName", param->country, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt countryName err!!! \n",__FUNCTION__,__LINE__);
- return -3;
- }
-
- //State or Province Name (full name) ST
- if( 0!=_name_entry_create_by_txt( name, entry, "stateOrProvinceName", param->stateOrProvince, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt stateOrProvinceName err!!! \n",__FUNCTION__,__LINE__);
- return -4;
- }
-
- //Locality Name (eg, city) L
- if( 0!=_name_entry_create_by_txt( name, entry, "localityName", param->locality, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt localityName err!!! \n",__FUNCTION__,__LINE__);
- return -5;
- }
-
- //Organization Name (eg, company) O
- if( 0!=_name_entry_create_by_txt( name, entry, "organizationName", param->organization, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt organizationName err!!! \n",__FUNCTION__,__LINE__);
- return -6;
- }
-
- //Organizational Unit Name (eg, section) OU
- if( 0!=_name_entry_create_by_txt( name, entry, "organizationalUnitName", param->organizationUnit, BUF_LEN) )
- {
- printf(" [%s %d] _name_entry_create_by_txt organizationalUnitName err!!! \n",__FUNCTION__,__LINE__);
- return -7;
- }
-
- /* subject name */
- //申请者信息
- ret = X509_REQ_set_subject_name(req, name);
- /* pub key */
- EVP_PKEY*pkey = EVP_PKEY_new();
- RSA*rsa = RSA_generate_key(bits, e, NULL, NULL);
- EVP_PKEY_assign_RSA(pkey, rsa);
- ret = X509_REQ_set_pubkey(req, pkey);
- /* 写入私钥PEM格式 */
- b = BIO_new_file(CUSTOM_CERT_KEY_PATH, "w");
- if(!PEM_write_bio_RSAPrivateKey( b, rsa, NULL,NULL, 0,0, NULL) )//往BIO中写入一个私钥,采用3DES加密
- printf("PEM_write_bio_RSAPrivateKey err!\n");
- BIO_free(b);
-
- /* 写入公钥PEM格式 */
- /*
- b = BIO_new_file("certpubkey.pem", "w");
- if (!PEM_write_bio_RSAPublicKey(b, rsa))
- printf("PEM_write_bio_RSAPublicKey err!\n");
- BIO_free(b);
- */
-
- md = EVP_sha1();
-
- ret = X509_REQ_digest(req, md, (unsigned char *)mdout, (unsigned int *)&mdlen);// 根据指定的摘要算法,对X509_REQ结构做摘要计算
- ret = X509_REQ_sign(req, pkey, md);
- if (!ret)
- {
- printf("sign err!\n");
- X509_REQ_free(req);
- return -8;
- }
-
- /* 写入文件PEM格式 */
- b = BIO_new_file(CUSTOM_CERT_REQ_PATH, "w");
- PEM_write_bio_X509_REQ(b, req );
- BIO_free(b);
- X509_REQ_free(req);
-
- return 0;
- }
-
- static int check_certs_availability(const char *p_ciphers, const char *p_ca, const char *p_cert,const char *p_private_key)
- {
- SSL_library_init();//必须加上不然有概率出现SSL_CTX_new返回NULL
- SSL_CTX *p_ssl_ctx = SSL_CTX_new((SSL_METHOD*)SSLv23_method());
-
- if (!p_ssl_ctx)
- {
- printf("Create SSL CTX fail!\n");
- SSL_CTX_free(p_ssl_ctx);
- p_ssl_ctx = NULL;
- return -1;
- }
- printf("new ssl ctx ok\n");
-
- //SSL_CTX_set_options((SSL_CTX*)p_ssl_ctx, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
- SSL_CTX_set_options(p_ssl_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
- SSL_CTX_set_mode(p_ssl_ctx, SSL_MODE_AUTO_RETRY |
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
- SSL_MODE_ENABLE_PARTIAL_WRITE |
- SSL_MODE_RELEASE_BUFFERS);
-
- /* 指定加密套件 */
- if (p_ciphers)//SERVER_CIPHERS
- {
- if (SSL_CTX_set_cipher_list(p_ssl_ctx, p_ciphers) != 1)
- {
- printf("Set cipher fail!\n");
- ERR_print_errors_fp(stderr);
- SSL_CTX_free(p_ssl_ctx);
- return -1;
- }
- printf("set cipher ok\n");
- }
-
- SSL_CTX_set_verify(p_ssl_ctx, SSL_VERIFY_NONE, NULL);//?
- /* 加载受信任的证书列表 */
- if (p_ca)
- {
- if (SSL_CTX_load_verify_locations(p_ssl_ctx, p_ca, NULL) == 0)
- {
- printf("Load trust CA [%s] fail!\n",p_ca);
- ERR_print_errors_fp(stderr);
- SSL_CTX_free(p_ssl_ctx);
- return -1;
- }
- printf("load [%s] ca ok\n",p_ca);
- }
-
- if ( NULL!=p_cert && !SSL_CTX_use_certificate_file(p_ssl_ctx, p_cert, X509_FILETYPE_PEM))
- {
- SSL_CTX_free(p_ssl_ctx);
- p_ssl_ctx = NULL;
- printf("Load cert [%s] fail!\n",p_cert);
- return -1;
- }
- printf("load cert [%s] ok\n",p_cert);
-
- if (NULL!=p_private_key && !SSL_CTX_use_PrivateKey_file(p_ssl_ctx, p_private_key, X509_FILETYPE_PEM))
- {
- SSL_CTX_free(p_ssl_ctx);
- p_ssl_ctx = NULL;
- printf("Load private key [%s] fail!\n",p_private_key);
- return -1;
- }
- printf("use private key [%s] ok\n",p_private_key);
-
- if (!SSL_CTX_check_private_key(p_ssl_ctx))
- {
- SSL_CTX_free(p_ssl_ctx);
- p_ssl_ctx = NULL;
- printf("Check private key fail!\n");
- return -1;
- }
- printf("@@@@@@@@@@ [ltz] check cert and private ok!!! \n");
-
- SSL_CTX_set_quiet_shutdown(p_ssl_ctx, 1);
-
- SSL_CTX_free(p_ssl_ctx);
-
- return 0;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。