1.MD5
主要由以下几个函数计算:MD5、MD5_Init、MD5_Update、MD5_Final
#include <openssl/md5.h>
#include <openssl/err.h>
//1.计算字符串
unsigned char MD5result[128]={0};
unsigned char inStr[4]={'1','2','3','4'} ;
size_t inStrSize=sizeof(inStr);
MD5(inStr,inStrSize,MD5result); //获取字符串的MD5值
//2.计算文件
unsigned char MD5result[128]={0};
MD5_CTX md5_ctx;
MD5_Init(&md5_ctx);
char readData[2048]={0};
while(!rfile.eof())
{
rfile.read(ReadBuff,sizeof(readBuff)); //以二进制方式读需要计算MD5的文件
int rlength = rfile.gcount();
if(rlength>0)
{
MD5_Update(&md5_ctx,readBuff,rlength); //将当前文件块加入,并更新MD5
}
}
MD5_Final(MD5result,&md5_ctx); //获取MD5值
2.AES
AES加密最常用ECB、CBC分组模式,以ECB模式128位加密zeropadding为例:
//userkey:用户指定的密码,可以通过MD5、sha等算法生成,也可以用户自定义(注意:密码长度只能是16、24、32字节,如果密码字符串长度不够,可以在字符串末尾追加一些特定的字符,或者重复密码字符串,直到满足最少的长度。)
#include <openssl/aes.h>
#include <openssl/evp.h>
//1.加密
int aes128_ecb_encrypt_zeropadding_evp(const unsigned char *userkey,int userkey_len, const unsigned char* plaintext,int plaintext_len, unsigned char *out_ciphetext)
{
if ( userkey_len<=0||
(!(userkey_len == 16 ||userkey_len== 24 ||userkey_len == 32))
)
{
return -1;
}
const unsigned char *data = plaintext;
unsigned char *encrypt =out_ciphetext;
const unsigned char *input_gen_key =userkey;
unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; ecb模式不需要iv偏移量
memset((void *)iv, 'i', EVP_MAX_IV_LENGTH);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int ret = 0;
int tlen = 0;
int mlen = 0;
int flen = 0;
/*初始化ctx*/
EVP_CIPHER_CTX_init(ctx);
/*指定加密算法及key和iv(此处IV没有用)*/
ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, input_gen_key, iv);
if (ret != 1)
{
printf("EVP_EncryptInit_ex failed\n");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
/*禁用padding功能*/
//EVP_CIPHER_CTX_set_padding(ctx, 0);
/*进行加密操作*/
ret = EVP_EncryptUpdate(ctx, encrypt, &mlen, data, plaintext_len);
if (ret != 1)
{
printf("EVP_EncryptUpdate failed\n");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
/*结束加密操作*/
ret = EVP_EncryptFinal_ex(ctx, encrypt + mlen, &flen);
if (ret != 1)
{
printf("EVP_EncryptFinal_ex failed\n");
return -1;
}
EVP_CIPHER_CTX_free(ctx);
return mlen + flen;
}
//2.AES解密
int AES128_ecb_decrypt_zeropadding_evp(const unsigned char *userkey,int userkey_len, const unsigned char*in_ciphetext,int in_ciphetext_len, unsigned char*out_plaintext)
{
if ( userkey_len<=0||
(!(userkey_len == 16 ||userkey_len== 24 ||userkey_len == 32))
)
{
return -1;
}
const unsigned char *data =in_ciphetext;
unsigned char *decrypt =out_plaintext;
const unsigned char *input_gen_key =userkey;
if (NULL == decrypt || NULL == data || NULL == input_gen_key)
{
return -1;
}
unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; ecb模式不需要iv偏移量
memset((void *)iv, 'i', EVP_MAX_IV_LENGTH);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int ret = 0;
int tlen = 0;
int mlen = 0;
int flen = 0;
EVP_CIPHER_CTX_init(ctx);
ret = EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, input_gen_key, iv);
if (ret != 1)
{
printf("EVP_DecryptInit_ex failed\n");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
/*禁用padding功能*/
//EVP_CIPHER_CTX_set_padding(ctx, 0);
ret = EVP_DecryptUpdate(ctx, decrypt, &mlen, data, in_ciphetext_len);
if (ret != 1)
{
printf("EVP_DecryptUpdate failed\n");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
ret = EVP_DecryptFinal_ex(ctx, decrypt + mlen, &flen);
if (ret != 1)
{
printf("EVP_DecryptFinal_ex failed\n");
}
EVP_CIPHER_CTX_free(ctx);
return mlen + flen;
}
3.RSA
以RSA512 padding为例,包括秘钥生成(PKCS#1/PKCS#8)、秘钥加载、加密解密
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
/*********************
*
* rsa的PKCS#1密钥头为‘-----BEGIN RSA PUBLIC KEY-----’,
* rsa的PKCS#8密钥头为‘-----BEGIN PUBLIC KEY-----’
* 对PKCS#1格式的密钥加载使用PEM_read_RSAPublicKey()函数
* 对PKCS#8格式公钥的加载使用PEM_read_RSA_PUBKEY()函数
*
* *********************/
int gen_pem_rsa512_pkcs1_pub_prvkey(const char *dir_path)
{
if (NULL == dir_path)
{
return -1;
}
int ret = -1;
RSA *rsa_key = RSA_new();
BIGNUM *bignum_t = BN_new();
int bits = 512;
FILE *prv_key_file = NULL;
FILE *pub_key_file = NULL;
char prv_key_path[512] = {0};
char pub_key_path[512] = {0};
snprintf(prv_key_path, sizeof(prv_key_path) - 1, "%s/myprv_pkcs1.pem", dir_path);
snprintf(pub_key_path, sizeof(pub_key_path) - 1, "%s/mypub_pkcs1.pem", dir_path);
prv_key_file = fopen(prv_key_path, "wb");
pub_key_file = fopen(pub_key_path, "wb");
if (NULL == rsa_key || NULL == bignum_t || NULL == prv_key_file || NULL == pub_key_file)
{
goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
}
BN_set_word(bignum_t, 65537);
if (1 != RSA_generate_key_ex(rsa_key, bits, bignum_t, NULL))
{
goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
}
if (1 != PEM_write_RSAPrivateKey(prv_key_file, rsa_key, NULL, NULL, 0, NULL, NULL))
{
goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
}
if (1 != PEM_write_RSAPublicKey(pub_key_file, rsa_key))
{
goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
}
ret = 0;
goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
clear_gen_pem_rsa512_pkcs1_pub_prvkey:
if (rsa_key)
RSA_free(rsa_key);
if (bignum_t)
BN_free(bignum_t);
if (prv_key_file)
fclose(prv_key_file);
if (pub_key_file)
fclose(pub_key_file);
return ret;
}
int gen_pem_rsa512_pkcs8_pub_prvKey(const char *dir_path)
{
if (NULL == dir_path)
{
return -1;
}
int ret = -1;
RSA *rsa_key = RSA_new();
BIGNUM *bignum_t = BN_new();
EVP_PKEY *evpkey = EVP_PKEY_new();
int bits = 512;
FILE *prv_key_file = NULL;
FILE *pub_key_file = NULL;
char prv_key_path[512] = {0};
char pub_key_path[512] = {0};
snprintf(prv_key_path, sizeof(prv_key_path) - 1, "%s/myprv_pkcs8.pem", dir_path);
snprintf(pub_key_path, sizeof(pub_key_path) - 1, "%s/mypub_pkcs8.pem", dir_path);
prv_key_file = fopen(prv_key_path, "wb");
pub_key_file = fopen(pub_key_path, "wb");
if (NULL == rsa_key || NULL == bignum_t || NULL == prv_key_file || NULL == pub_key_file || NULL == evpkey)
{
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
}
BN_set_word(bignum_t, 65537);
if (1 != RSA_generate_key_ex(rsa_key, bits, bignum_t, NULL))
{
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
}
if (1 != EVP_PKEY_set1_RSA(evpkey, rsa_key))
{
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
}
if (1 != PEM_write_PrivateKey(prv_key_file, evpkey, NULL, NULL, 0, NULL, NULL))
{
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
}
if (1 != PEM_write_PUBKEY(pub_key_file, evpkey))
{
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
}
ret = 0;
goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
clear_gen_pem_rsa512_pkcs8_pub_prvKey:
if (rsa_key)
RSA_free(rsa_key);
if (bignum_t)
BN_free(bignum_t);
if (evpkey)
EVP_PKEY_free(evpkey);
if (prv_key_file)
fclose(prv_key_file);
if (pub_key_file)
fclose(pub_key_file);
return ret;
}
int read_pubkey_pem_rsa512_pkcs1(const char *key_path, RSA **out_rsa)
{
if (NULL == key_path)
{
return -1;
}
FILE *pf_key = NULL;
pf_key = fopen(key_path, "rb");
if (NULL == pf_key)
{
return -1;
}
*out_rsa = RSA_new();
if (NULL == out_rsa)
{
fclose(pf_key);
return -1;
}
*out_rsa = PEM_read_RSAPublicKey(pf_key, out_rsa, NULL, NULL);
fclose(pf_key);
return 0;
}
int read_pubkey_pem_rsa512_pkcs8(const char *key_path, RSA **out_rsa)
{
if (NULL == key_path)
{
return -1;
}
FILE *pf_key = NULL;
pf_key = fopen(key_path, "rb");
if (NULL == pf_key)
{
return -1;
}
EVP_PKEY* rsa_evp=NULL;
rsa_evp= PEM_read_PUBKEY(pf_key, &rsa_evp, NULL, NULL);
*out_rsa = EVP_PKEY_get1_RSA(rsa_evp);
//RSA_print_fp(stdout, *out_rsa, 0);
EVP_PKEY_free(rsa_evp);
fclose(pf_key);
return 0;
}
int read_prvkey_pem_rsa512_pkcs1(const char *key_path, RSA **out_rsa)
{
if (NULL == key_path)
{
return -1;
}
FILE *pf_key = NULL;
pf_key = fopen(key_path, "rb");
if (NULL == pf_key)
{
return -1;
}
*out_rsa = RSA_new();
if (NULL == out_rsa)
{
fclose(pf_key);
return -1;
}
*out_rsa = PEM_read_RSAPrivateKey(pf_key, out_rsa, NULL, NULL);
//RSA_print_fp(stdout, *out_rsa, 0);
fclose(pf_key);
return 0;
}
int read_prvkey_pem_rsa512_pkcs8(const char *key_path, RSA **out_rsa)
{
if (NULL == key_path)
{
return -1;
}
FILE *pf_key = NULL;
pf_key = fopen(key_path, "rb");
if (NULL == pf_key)
{
return -1;
}
EVP_PKEY *rsa_evp=NULL;
rsa_evp= PEM_read_PrivateKey(pf_key, &rsa_evp, NULL, NULL);
*out_rsa = EVP_PKEY_get1_RSA(rsa_evp);
//RSA_print_fp(stdout, *out_rsa, 0);
EVP_PKEY_free(rsa_evp);
fclose(pf_key);
return 0;
}
int pub_encrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
size_t total_len=0;
size_t loop=input_len/64;
for(int i=0;i<loop;i++)
{
size_t len=0;
len=RSA_public_encrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len+=len;
}
size_t final_len=0;
final_len=RSA_public_encrypt(input_len%64,in_data+loop*64, out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len=total_len+final_len;
*out_len=total_len;
return 0;
}
int pub_decrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
//RSA_print_fp(stdout, rsa_key, 0);
size_t total_len=0;
size_t loop=input_len/64;
for(int i=0;i<loop;i++)
{
size_t len=0;
len=RSA_public_decrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len+=len;
}
*out_len=total_len;
return 0;
}
int prv_encrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
size_t total_len=0;
size_t loop=input_len/64;
for(int i=0;i<loop;i++)
{
size_t len=0;
len=RSA_private_encrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len+=len;
}
size_t final_len=0;
final_len=RSA_private_encrypt(input_len%64,in_data+loop*64, out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len=total_len+final_len;
*out_len=total_len;
return 0;
}
int prv_decrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
//RSA_print_fp(stdout, rsa_key, 0);
size_t total_len=0;
size_t loop=input_len/64;
for(int i=0;i<loop;i++)
{
size_t len=0;
len=RSA_private_decrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
total_len+=len;
}
*out_len=total_len;
return 0;
}