openssl的计算MD5、AES、RSA
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; }