OpenSSL 1.1.1和3.0.5的编译及使用

2022-11-21 12:28:42

编译安装openssl,需要先安装如下一些工具,选择32bit

  • Perl
  • Nasm

 安装后设置环境变量:

 下载openssl 1.1.1版本

 用管理员身份打开[x86 Native Tools Command Prompt for VS 2019],执行如下指令:

#Step1:

#若需要编译静态库需要增加no-shared参数,否则默认生成动态库

#perl Configure VC-WIN32 no-shared --prefix=C:\Users\Username\Desktop\openssl\output\32

perl Configure VC-WIN32 --prefix=C:\Users\Username\Desktop\openssl\output\32

#Step2:

nmake

#Step3:

nmake test

#Step4:

nmake install

完成的编译,生成如下文件:

静态库版本:头文件、libcrypto.liblibssl.lib

动态库版本(32位):头文件、libcrypto.lib、libssl.lib、libcrypto-1_1.dll、libssl-1_1.dll

动态库版本(64位):头文件、libcrypto.lib、libssl.lib、libcrypto-1_1-x64.dll、libssl-1_1-x64.dll

接下来新建工程,选择工程 -属性 -配置属性 - VC++目录:    3.开始写代码。首先

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/md5.h>
#include <openssl/rsa.h>

#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")

#define _CRT_SECURE_NO_WARNINGS

int MD5(const char* data, char* buf)
{
	MD5_CTX ctx;
	unsigned char md[16];
	char tmp[3] = { '\0' };
	int i;

	MD5_Init(&ctx);
	MD5_Update(&ctx, data, strlen(data));
	MD5_Final(md, &ctx);

	for (i = 0; i < 16; i++) {
		sprintf(tmp, "%02x", md[i]);
		strcat(buf, tmp);
	}
	return 0;
}

int main()
{
    //std::cout << "Hello World!\n";
	char szBuf[1024] = { 0 }, szMd5[50] = { 0 };
	gets_s(szBuf, _countof(szBuf));
	MD5(szBuf, szMd5);
	printf("%s\n", szMd5);
	RSA_private_encrypt();
	return 0;
}

如果用openssl3.0.5版本的话,则使用下面的编译方法:

用管理员身份运行cmd,执行下面的操作:

cd c:\openssl-3.0.5

perl Configure VC-WIN64A --prefix=D:\SoftwareDev\openssl-openssl-3.0.5\install

以管理员身份执行:x64 Native Tools Command Prompt for VS 2022

 先执行下批处理文件:

然后执行nmake install

在install目录中生成了和openssl1.1.1一样目录结构的include和lib文件。

 接下来使用openssl3.0.5时,会发现有个x64的问题,也就是这个库是64位的,如果VC++用的是win32或x86的配置,则需要对应改为x64。RSA的使用如下:



void generateKeys() {
    EVP_PKEY* pkey = EVP_RSA_gen(1024);
    if (pkey == NULL) {
        fprintf(stderr, "error: rsa gen\n");
        ERR_print_errors_fp(stderr);
        return;
    }
    FILE* fp = fopen("public.txt", "wt");
    if (fp != NULL) {
        PEM_write_PUBKEY(fp, pkey);
        fclose(fp);
    }
    else {
        perror("file error");
    }
    fp = fopen("private.txt", "wt");
    if (fp != NULL) {
        PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
        fclose(fp);
    }
    else {
        perror("file error");
    }
    EVP_PKEY_free(pkey);
}

unsigned char* encrypt(unsigned char* src, unsigned int len, int* length)
{
    FILE* fp = fopen("public.txt", "r");
    if (fp == NULL) {
        perror("file error");
        return NULL;
    }
    EVP_PKEY* pkey;
    pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
    fclose(fp);
    if (pkey == NULL) {
        fprintf(stderr, "error: read publics key\n");
        return NULL;
    }
    EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
    EVP_PKEY_encrypt_init(ctx);
    unsigned char* dst = (unsigned char*)malloc(2048);
    size_t outl=2048;
    if (!EVP_PKEY_encrypt(ctx, dst, &outl, src, (size_t)len)) {
        fprintf(stderr, "error: encrypt\n");
        EVP_PKEY_free(pkey);
        free(dst);
        return NULL;
    }
    int len2 = outl;
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx);
    BIO_dump_fp(stdout, dst, len2);
    printf("len: %d, len2: %d\n", len, len2);
    if (length != NULL) {
        *length = len2;
    }
    return dst;
}

unsigned char* decrypt(unsigned char* src, int len) {
    FILE* fp = fopen("private.txt", "r");
    if (fp == NULL) {
        perror("file error");
        return NULL;
    }
    EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);
    if (pkey == NULL) {
        fprintf(stderr, "error: read private key\n");
        return NULL;
    }
    EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
    EVP_PKEY_decrypt_init(ctx);
    unsigned char* dst = (unsigned char*)malloc(2048);
    size_t outl=2048;
    size_t inl = len;
    if (!EVP_PKEY_decrypt(ctx, dst, &outl, src, inl)) {
        fprintf(stderr, "error: decrypt\n");
        free(dst);
        dst = NULL;
    }
    else {
        BIO_dump_fp(stdout, dst, (int)outl);
        printf("len: %d, outl: %lld\n", len, outl);
    }
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx);
    return dst;
}

  • 作者:芯片-嵌入式
  • 原文链接:https://blog.csdn.net/weixin_49369227/article/details/127464259
    更新时间:2022-11-21 12:28:42