openssl的编译
win下openssl 编译
x86环境,请输入
perl Configure VC-WIN32 no-asm --prefix="D:\workspace\openssl-1.1.1b\x86"
如果是x64环境 , 请输入
perl Configure VC-WIN64A no-asm --prefix="D:\workspace\openssl-1.1.1b\x64"
其中, --prefix=是指定的库和工具头文件等最终输出目录,请根据实际进行修改
在x86和x64下各自执行
nmake
nmake test
nmake install
nmake clean
openssl的测试例子
#include <iostream>
#include <cassert>
#include <string>
#include <vector>
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
#include <fstream>
#include "openssl/md5.h"
#include "openssl/sha.h"
#include "openssl/des.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include "openssl/aes.h"
#include "openssl/err.h"
#define RELESE(P) if (P) \
{ \
delete P; \
P = NULL; \
}
#define RELESE_ARRAY(P) if (P) \
{ \
delete[] P; \
P = NULL; \
}
// ---- md5摘要哈希 ---- //
void md5(const std::string& srcStr, std::string& encodedStr, std::string& encodedHexStr)
{
// 调用md5哈希
unsigned char mdStr[33] = { 0 };
MD5((const unsigned char*)srcStr.c_str(), srcStr.length(), mdStr);
// 哈希后的字符串
encodedStr = std::string((const char*)mdStr);
// 哈希后的十六进制串 32字节
char buf[65] = { 0 };
char tmp[3] = { 0 };
for (int i = 0; i < 32; i++)
{
sprintf(tmp, "%02x", mdStr[i]);
strcat(buf, tmp);
}
buf[32] = '\0'; // 后面都是0,从32字节截断
encodedHexStr = std::string(buf);
}
// ---- sha256摘要哈希 ---- //
void sha256(const std::string& srcStr, std::string& encodedStr, std::string& encodedHexStr)
{
// 调用sha256哈希
unsigned char mdStr[33] = { 0 };
SHA256((const unsigned char*)srcStr.c_str(), srcStr.length(), mdStr);
// 哈希后的字符串
encodedStr = std::string((const char*)mdStr);
// 哈希后的十六进制串 32字节
char buf[65] = { 0 };
char tmp[3] = { 0 };
for (int i = 0; i < 32; i++)
{
sprintf(tmp, "%02x", mdStr[i]);
strcat(buf, tmp);
}
buf[32] = '\0'; // 后面都是0,从32字节截断
encodedHexStr = std::string(buf);
}
// ---- des对称加解密 ---- //
// 加密 ecb模式
std::string des_encrypt(const std::string& clearText, const std::string& key)
{
std::string cipherText; // 密文
DES_cblock keyEncrypt;
memset(keyEncrypt, 0, 8);
// 构造补齐后的密钥
if (key.length() <= 8)
memcpy(keyEncrypt, key.c_str(), key.length());
else
memcpy(keyEncrypt, key.c_str(), 8);
// 密钥置换
DES_key_schedule keySchedule;
DES_set_key_unchecked(&keyEncrypt, &keySchedule);
// 循环加密,每8字节一次
const_DES_cblock inputText;
DES_cblock outputText;
std::vector<unsigned char> vecCiphertext;
unsigned char tmp[8];
for (int i = 0; i < clearText.length() / 8; i++)
{
memcpy(inputText, clearText.c_str() + i * 8, 8);
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
{
vecCiphertext.push_back(tmp[j]);
}
}
if (clearText.length() % 8 != 0)
{
int tmp1 = clearText.length() / 8 * 8;
int tmp2 = clearText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, clearText.c_str() + tmp1, tmp2);
// 加密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
{
vecCiphertext.push_back(tmp[j]);
}
}
cipherText.clear();
cipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
return cipherText;
}
// 解密 ecb模式
std::string des_decrypt(const std::string & cipherText, const std::string & key)
{
std::string clearText; // 明文
DES_cblock keyEncrypt;
memset(keyEncrypt, 0, 8);
if (key.length() <= 8)
memcpy(keyEncrypt, key.c_str(), key.length());
else
memcpy(keyEncrypt, key.c_str(), 8);
DES_key_schedule keySchedule;
DES_set_key_unchecked(&keyEncrypt, &keySchedule);
const_DES_cblock inputText;
DES_cblock outputText;
std::vector<unsigned char> vecCleartext;
unsigned char tmp[8];
for (int i = 0; i < cipherText.length() / 8; i++)
{
memcpy(inputText, cipherText.c_str() + i * 8, 8);
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}
if (cipherText.length() % 8 != 0)
{
int tmp1 = cipherText.length() / 8 * 8;
int tmp2 = cipherText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
// 解密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}
clearText.clear();
clearText.assign(vecCleartext.begin(), vecCleartext.end());
return clearText;
}
// ---- rsa非对称加解密 ---- //
#define KEY_LENGTH 2048 // 密钥长度
#define PUB_KEY_FILE "pubkey.pem" // 公钥路径
#define PRI_KEY_FILE "prikey.pem" // 私钥路径
// 函数方法生成密钥对
void generateRSAKey(std::string strKey[2])
{
// 公私密钥对
size_t pri_len;
size_t pub_len;
char* pri_key = NULL;
char* pub_key = NULL;
// 生成密钥对
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);
PEM_write_bio_RSAPublicKey(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';
// 存储密钥对
strKey[0] = pub_key;
strKey[1] = pri_key;
// 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)
FILE * pubFile = fopen(PUB_KEY_FILE, "w");
if (pubFile == NULL)
{
assert(false);
return;
}
fputs(pub_key, pubFile);
fclose(pubFile);
FILE* priFile = fopen(PRI_KEY_FILE, "w");
if (priFile == NULL)
{
assert(false);
return;
}
fputs(pri_key, priFile);
fclose(priFile);
// 内存释放
RSA_free(keypair);
BIO_free_all(pub);
BIO_free_all(pri);
free(pri_key);
free(pub_key);
}
// 命令行方法生成公私钥对(begin public key/ begin private key)
// 找到openssl命令行工具,运行以下
// openssl genrsa -out prikey.pem 1024
// openssl rsa - in privkey.pem - pubout - out pubkey.pem
// 公钥加密
std::string rsa_pub_encrypt(const std::string & clearText, const std::string & pubKey)
{
std::string strRet;
RSA* rsa = NULL;
BIO* keybio = BIO_new_mem_buf((unsigned char*)pubKey.c_str(), -1);
// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
RSA * pRSAPublicKey = RSA_new();
rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
int len = RSA_size(rsa);
char* encryptedText = (char*)malloc(len + 1);
memset(encryptedText, 0, len + 1);
// 加密函数
int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);
// 释放内存
free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
// 私钥解密
std::string rsa_pri_decrypt(const std::string & cipherText, const std::string & priKey)
{
std::string strRet;
RSA* rsa = RSA_new();
BIO* keybio;
keybio = BIO_new_mem_buf((unsigned char*)priKey.c_str(), -1);
// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
int len = RSA_size(rsa);
char* decryptedText = (char*)malloc(len + 1);
memset(decryptedText, 0, len + 1);
// 解密函数
int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
// 释放内存
free(decryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
// AES文件加密函数 ///////////////////////////////////////////////////////////
int TestAesEncryptFile(std::string in_file_path, std::string out_file_path, char Key[32])
{
int encrypt_chunk_size = 16;
std::ifstream fin(in_file_path.c_str(), std::ios::binary);
std::ofstream fout(out_file_path, std::ios::binary);
if (!fin)
{
std::cout << "Can not open fin file." << std::endl;
return 1;
}
if (!fout)
{
std::cout << "Can not open fout file." << std::endl;
return 1;
}
//用指定密钥对一段内存进行加密,结果放在outbuffer中
unsigned char aes_keybuf[32];
memset(aes_keybuf, 0, sizeof(aes_keybuf));
strcpy((char*)aes_keybuf, Key);
AES_KEY aeskey;
AES_set_encrypt_key(aes_keybuf, 256, &aeskey);
char* in_data = new char[encrypt_chunk_size + 1];
char* out_data = new char[encrypt_chunk_size + 1];
while (!fin.eof())
{
fin.read(in_data, encrypt_chunk_size);
if (fin.gcount() < encrypt_chunk_size)
{
fout.write(in_data, fin.gcount());
}
else
{
AES_encrypt((const unsigned char*)in_data, (unsigned char*)out_data, &aeskey);
fout.write(out_data, fin.gcount());
}
};
fout.close();
fin.close();
RELESE_ARRAY(in_data);
RELESE_ARRAY(out_data);
return 0;
}
// AES文件解密函数 //////////////////////////////////////////////////////////
int TestAesDecryptFile(std::string in_file_path, std::string out_file_path, char Key[32])
{
int encrypt_chunk_size = 16;
std::ifstream fin(in_file_path.c_str(), std::ios::binary);
std::ofstream fout(out_file_path, std::ios::binary);
if (!fin)
{
std::cout << "Can not open fin file." << std::endl;
return 1;
}
if (!fout)
{
std::cout << "Can not open fout file." << std::endl;
return 1;
}
//用指定密钥对一段内存进行加密,结果放在outbuffer中
unsigned char aes_keybuf[32];
memset(aes_keybuf, 0, sizeof(aes_keybuf));
strcpy((char*)aes_keybuf, Key);
AES_KEY aeskey;
AES_set_decrypt_key(aes_keybuf, 256, &aeskey);
char* in_data = new char[encrypt_chunk_size + 1];
char* out_data = new char[encrypt_chunk_size + 1];
int i = 0;
while (!fin.eof())
{
fin.read(in_data, encrypt_chunk_size);
if (fin.gcount() < encrypt_chunk_size)
{
fout.write(in_data, fin.gcount());
}
else
{
AES_decrypt((unsigned char*)in_data, (unsigned char*)out_data, &aeskey);
fout.write(out_data, fin.gcount());
}
};
fout.close();
fin.close();
RELESE_ARRAY(in_data);
RELESE_ARRAY(out_data);
return 0;
}
int main(int argc, char** argv)
{
time_t t1, t2, t3, t4;
t1 = time(NULL);
printf("加解密起始时间: %s\n", ctime(&t1));
char strkey[] = "xxyy1234567890";
TestAesEncryptFile("D://test.txt", "D://test.txtkey", strkey);
t2 = time(NULL);
printf("AES256加密成功!\n");
printf("加密用时: %lld秒\n", (t2 - t1));
t3 = time(NULL);
TestAesDecryptFile("D://test.txtkey", "D://test1.txt", strkey);
t4 = time(NULL);
printf("AES256解密成功!\n");
printf("解密用时: %lld秒\n", (t4 - t3));
/*
BYTE userKey[AES_BLOCK_SIZE];
unsigned char* data = (unsigned char*)malloc(AES_BLOCK_SIZE * 3);
unsigned char* encrypto = (unsigned char*)malloc(AES_BLOCK_SIZE * 3);
unsigned char* plain = (unsigned char*)malloc(AES_BLOCK_SIZE * 3);
AES_KEY key;
memcpy(userKey, "zheshiopensslexq", 16);
memset((void*)data, 'p', AES_BLOCK_SIZE * 3);
memset((void*)encrypto, 0, AES_BLOCK_SIZE * 3);
memset((void*)plain, 0, AES_BLOCK_SIZE * 3);
//设置加密key及秘钥长度
//理论上AES加密是根据S盒进行字节替换的,因此原文和密文个字节一一对应大小相同
AES_set_encrypt_key((const unsigned char*)userKey, AES_BLOCK_SIZE * 8, &key);
int len = 0;
//循环加密, 每次加密长度是AES_BLOCK_SIZE长度的数据
while (len < AES_BLOCK_SIZE * 3)
{
AES_encrypt(data + len, encrypto + len, &key);
len += AES_BLOCK_SIZE;
}
//设置解密key及秘钥长度
AES_set_decrypt_key((const unsigned char*)userKey, AES_BLOCK_SIZE * 8, &key);
len = 0;
//循环解密
//每次输入16字节,输出16字节,如果不够需要填充
while (len < AES_BLOCK_SIZE * 3)
{
AES_decrypt(encrypto + len, plain + len, &key);
len += AES_BLOCK_SIZE;
}
//解密后与元数据是否一致
if (memcmp(plain, data, AES_BLOCK_SIZE * 3) == 0)
{
printf("test success\n");
}
else
{
printf("test failed\n");
}
return 0;
unsigned char buf[16];
memset(buf, 1, sizeof(buf));
strcpy((char*)buf, "thisisexample");
std::cout << "current buf value is :" << buf << std::endl;
unsigned char buf2[16];
unsigned char buf3[16];
unsigned char aes_keybuf[32];
memset(aes_keybuf, 0, sizeof(aes_keybuf));
strcpy((char*)aes_keybuf, "key1");
std::cout << "current aes_keybuf value is :" << aes_keybuf << std::endl;
AES_KEY aeskey;
AES_set_encrypt_key(aes_keybuf, 256, &aeskey);
//cout << "AESkey is:" << aeskey << endl;
AES_encrypt(buf, buf2, &aeskey);
std::cout << "current buf2 value is :" << buf2 << std::endl;
memset(aes_keybuf, 0, sizeof(aes_keybuf));
strcpy((char*)aes_keybuf, "key1");
std::cout << "current aes_keybuf value is :" << aes_keybuf << std::endl;
AES_set_decrypt_key(aes_keybuf, 256, &aeskey);
AES_decrypt(buf2, buf3, &aeskey);
std::cout << "current buf2 value is :" << buf2 << std::endl;
std::cout << "*********************************" << std::endl;
std::cout << "current buf3 value is :" << buf3 << std::endl;
if (memcmp(buf, buf3, sizeof(buf)) == 0)
printf("AES256 test success\r\n");
else
printf("AES256 test fail\r\n");
return 0;
// 原始明文
std::string srcText = "this is an example";
std::string encryptText;
std::string encryptHexText;
std::string decryptText;
std::cout << "=== 原始明文 ===" << std::endl;
std::cout << srcText << std::endl;
// md5
std::cout << "=== md5哈希 ===" << std::endl;
md5(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;
// sha256
std::cout << "=== sha256哈希 ===" << std::endl;
sha256(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;
// des
std::cout << "=== des加解密 ===" << std::endl;
std::string desKey = "1234567890";
encryptText = des_encrypt(srcText, desKey);
std::cout << "加密字符: " << std::endl;
std::cout << encryptText << std::endl;
decryptText = des_decrypt(encryptText, desKey);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;
// rsa
std::cout << "=== rsa加解密 ===" << std::endl;
std::string key[2];
generateRSAKey(key);
std::cout << "公钥: " << std::endl;
std::cout << key[0] << std::endl;
std::cout << "私钥: " << std::endl;
std::cout << key[1] << std::endl;
encryptText = rsa_pub_encrypt(srcText, key[0]);
std::cout << "加密字符: " << std::endl;
std::cout << encryptText << std::endl;
decryptText = rsa_pri_decrypt(encryptText, key[1]);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;
system("pause");
return 0;
*/
}