C++ 使用OpenSSL

最近在研究C++使用OpenSSL,前面的文章介绍了编译OpenSSL源码的过程,这里随便写下加密解密的用法。

MD5:

#include <openssl\md5.h>
#include <iostream>
using namespace std;

int md5_encrypt(const void* data, size_t len, unsigned char* md5)
{
	if (data == NULL || len <= 0 || md5 == NULL) {
		printf("Input param invalid!\n");
		return -1;
	}
	MD5_CTX ctx;
	MD5_Init(&ctx);
	MD5_Update(&ctx, data, len);
	MD5_Final(md5, &ctx);

	return 0;
}

AES:

#include <openssl\aes.h>

int aes_encrypt(const unsigned char* data, const size_t len, const unsigned char* key, unsigned char* ivec, unsigned char* encrypt_data)
{
	AES_KEY aes_key;
	memset(&aes_key, 0x00, sizeof(AES_KEY));
	if (AES_set_encrypt_key(key, 128, &aes_key) < 0)
	{
		fprintf(stderr, "Unable to set encryption key in AES...\n");
		return -1;
	}
	AES_cbc_encrypt(data, encrypt_data, len, &aes_key, ivec, AES_ENCRYPT);
	return 0;
}

int aes_decrypt(const unsigned char* encrypt_data, const size_t len, const unsigned char* key, unsigned char* ivec, unsigned char* decrypt_data)
{
	AES_KEY aes_key;
	memset(&aes_key, 0x00, sizeof(AES_KEY));
	if (AES_set_decrypt_key(key, 128, &aes_key) < 0)
	{
		fprintf(stderr, "Unable to set decryption key in AES...\n");
		return -1;
	}
	AES_cbc_encrypt(encrypt_data, decrypt_data, len, &aes_key, ivec, AES_DECRYPT);
	return 0;
}

EVP:

#include <openssl\evp.h>


int evp_aes_cbc_encrypt(const unsigned char* data, const int len, const unsigned char* key, unsigned char* ivec, unsigned char* encrypt_data, int& encrypt_len)
{
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	ASSERT(ctx);
	int out_len;
	int ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, ivec);
	if (ret != 1)
	{
		return -1;
	}
	EVP_CIPHER_CTX_set_key_length(ctx, EVP_MAX_KEY_LENGTH);
	EVP_CIPHER_CTX_set_padding(ctx, 5);
	ret = EVP_EncryptUpdate(ctx, encrypt_data, &out_len, data, len);
	if (ret != 1)
	{
		return -1;
	}
	encrypt_len = out_len;
	ret = EVP_EncryptFinal_ex(ctx, encrypt_data + encrypt_len, &out_len);
	if (ret != 1)
	{
		return -1;
	}
	encrypt_len += out_len;
	EVP_CIPHER_CTX_free(ctx);
	return 0;
}

int evp_aes_cbc_decrypt(const unsigned char* encrypt_data, const int len, const unsigned char* key, unsigned char* ivec, unsigned char* decrypt_data, int& decrypt_len)
{
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	ASSERT(ctx);
	int out_len;
	int ret = EVP_DecryptInit(ctx, EVP_aes_128_cbc(), key, ivec);
	if (ret != 1)
	{
		return -1;
	}
	EVP_CIPHER_CTX_set_key_length(ctx, EVP_MAX_KEY_LENGTH);
	ret = EVP_DecryptUpdate(ctx, decrypt_data, &out_len, encrypt_data, len);
	if (ret != 1)
	{
		return -1;
	}
	decrypt_len = out_len;
	ret = EVP_DecryptFinal_ex(ctx, decrypt_data + decrypt_len, &out_len);
	if (ret != 1)
	{
		return -1;
	}
	decrypt_len += out_len;
	EVP_CIPHER_CTX_free(ctx);

	return 0;
}

 

RSA:

#include <openssl\rsa.h>
#include <openssl\pem.h>
#include <openssl\rand.h>
#include <iostream>

#define PUBLIC_KEY_FILE "rsapub.key"
#define PRIVATE_KEY_FILE "rsapriv.key"
#define RSA_KEY_LENGTH 1024
#define RSA_PRIKEY_PSW "123"


int rsa_test(const unsigned char* data, size_t& len, char* encrypt_data, size_t& encrypt_data_len, char* decrypt_data, size_t& decrypt_data_len)
{
	
	generate_key_files(PUBLIC_KEY_FILE, PRIVATE_KEY_FILE,(const unsigned char *)RSA_PRIKEY_PSW, strlen(RSA_PRIKEY_PSW));
	EVP_PKEY *pub_key = open_public_key(PUBLIC_KEY_FILE);
	EVP_PKEY *pri_key = open_private_key(PRIVATE_KEY_FILE, (const unsigned char *)RSA_PRIKEY_PSW);
	int ret = rsa_key_encrypt(pub_key, data, len, (unsigned char *)encrypt_data, encrypt_data_len);
	if (ret != 0)
	{
		printf("rsa encrypt failed!\n");
		return ret;
	}
	else
	{
		printf("rsa encrypt success!\n");
	}
	ret = rsa_key_decrypt(pri_key, (const unsigned char *)encrypt_data, encrypt_data_len, (unsigned char *)decrypt_data, decrypt_data_len);
	if (ret != 0)
	{
		printf("rsa decrypt failed!\n");
	}
	else
	{
		printf("rsa decrypt success!\n");
		printf("encrypt data:%s\n", encrypt_data);
		printf("decrypt data:%s\n", decrypt_data);
	}
	return ret;
}

int generate_key_files(const char* pub_key_file, const char* priv_key_file, const unsigned char* passwd, int passwd_len)
{
	RSA *rsa = NULL;
	rsa = RSA_generate_key(RSA_KEY_LENGTH, RSA_F4, NULL, NULL);
	if (rsa == NULL)
	{
		printf("RSA_generate_key error!\n");
		return -1;
	}

	//生成公钥文件
	BIO* bio_pub = BIO_new(BIO_s_file());
	if (NULL == bio_pub)
	{
		printf("generate_key bio file new error!\n");
		return -1;
	}
	if (BIO_write_filename(bio_pub, (void *)pub_key_file) <= 0)
	{
		printf("BIO_write_filename error!\n");
		return -1;
	}

	if (PEM_write_bio_RSAPublicKey(bio_pub, rsa) != 1)
	{
		printf("PEM_write_bio_RSAPublicKey error!\n");
		return -1;
	}
	printf("Create public key ok!\n");
	BIO_free_all(bio_pub);

	// 生成私钥文件
	BIO* bio_priv = BIO_new_file(priv_key_file, "w+");
	if (NULL == bio_priv)
	{
		printf("generate_key bio file new error2!\n");
		return -1;
	}
	if (PEM_write_bio_RSAPrivateKey(bio_priv, rsa, EVP_des_ede3_ofb(), (unsigned char *)passwd, passwd_len, NULL, NULL) != 1)
	{
		printf("PEM_write_bio_RSAPublicKey error!\n");
		return -1;
	}
	printf("Create private key ok!\n");
	BIO_free_all(bio_priv);

	RSA_free(rsa);

	return 0;
}

EVP_PKEY* open_public_key(const char* pub_key_file)
{
	EVP_PKEY* key = NULL;
	RSA *rsa = NULL;

	OpenSSL_add_all_algorithms();
	BIO *bio_pub = BIO_new(BIO_s_file());;
	BIO_read_filename(bio_pub, pub_key_file);
	if (NULL == bio_pub)
	{
		printf("open_public_key bio file new error!\n");
		return NULL;
	}

	rsa = PEM_read_bio_RSAPublicKey(bio_pub, NULL, NULL, NULL);
	if (rsa == NULL)
	{
		printf("open_public_key failed to PEM_read_bio_RSAPublicKey!\n");
		BIO_free(bio_pub);
		RSA_free(rsa);

		return NULL;
	}

	printf("open_public_key success to PEM_read_bio_RSAPublicKey!\n");
	key = EVP_PKEY_new();
	if (NULL == key)
	{
		printf("open_public_key EVP_PKEY_new failed\n");
		RSA_free(rsa);

		return NULL;
	}

	EVP_PKEY_assign_RSA(key, rsa);
	return key;
}

EVP_PKEY* open_private_key(const char* priv_key_file, const unsigned char *passwd)
{
	EVP_PKEY* key = NULL;
	RSA *rsa = RSA_new();
	OpenSSL_add_all_algorithms();
	BIO* bio_priv = NULL;
	bio_priv = BIO_new_file(priv_key_file, "rb");
	if (NULL == bio_priv)
	{
		printf("open_private_key bio file new error!\n");

		return NULL;
	}

	rsa = PEM_read_bio_RSAPrivateKey(bio_priv, &rsa, NULL, (void *)passwd);
	if (rsa == NULL)
	{
		printf("open_private_key failed to PEM_read_bio_RSAPrivateKey!\n");
		BIO_free(bio_priv);
		RSA_free(rsa);

		return NULL;
	}

	printf("open_private_key success to PEM_read_bio_RSAPrivateKey!\n");
	key = EVP_PKEY_new();
	if (NULL == key)
	{
		printf("open_private_key EVP_PKEY_new failed\n");
		RSA_free(rsa);

		return NULL;
	}

	EVP_PKEY_assign_RSA(key, rsa);
	return key;
}

int rsa_key_encrypt(EVP_PKEY *key, const unsigned char* data, size_t len, unsigned char *encrypt_data, size_t &encrypt_data_len)
{
	EVP_PKEY_CTX *ctx = NULL;
	OpenSSL_add_all_ciphers();

	ctx = EVP_PKEY_CTX_new(key, NULL);
	if (NULL == ctx)
	{
		printf("ras_pubkey_encryptfailed to open ctx.\n");
		EVP_PKEY_free(key);
		return -1;
	}

	if (EVP_PKEY_encrypt_init(ctx) <= 0)
	{
		printf("ras_pubkey_encryptfailed to EVP_PKEY_encrypt_init.\n");
		EVP_PKEY_free(key);
		return -1;
	}

	if (EVP_PKEY_encrypt(ctx, encrypt_data, &encrypt_data_len, data, len) <= 0)
	{
		printf("ras_pubkey_encryptfailed to EVP_PKEY_encrypt.\n");
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);

		return -1;
	}

	EVP_PKEY_CTX_free(ctx);
	EVP_PKEY_free(key);

	return 0;
}

int rsa_key_decrypt(EVP_PKEY *key, const unsigned char *encrypt_data, size_t encrypt_data_len, unsigned char *decrypt_data, size_t &decrypt_data_len)
{
	EVP_PKEY_CTX *ctx = NULL;
	OpenSSL_add_all_ciphers();

	ctx = EVP_PKEY_CTX_new(key, NULL);
	if (NULL == ctx)
	{
		printf("ras_prikey_decryptfailed to open ctx.\n");
		EVP_PKEY_free(key);
		return -1;
	}

	if (EVP_PKEY_decrypt_init(ctx) <= 0)
	{
		printf("ras_prikey_decryptfailed to EVP_PKEY_decrypt_init.\n");
		EVP_PKEY_free(key);
		return -1;
	}

	if (EVP_PKEY_decrypt(ctx, decrypt_data, &decrypt_data_len, encrypt_data, encrypt_data_len) <= 0)
	{
		printf("ras_prikey_decryptfailed to EVP_PKEY_decrypt.\n");
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);

		return -1;
	}

	EVP_PKEY_CTX_free(ctx);
	EVP_PKEY_free(key);
	return 0;
}

 

  • 3
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值