编译安装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.lib、libssl.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;
}