1)示例1
#include <string.h>
#include <openssl/evp.h>
int main()
{
int ret,which=1;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher;
unsigned char key[24],iv[8],in[100],out[108],de[100];
int i,len,inl,outl,total=0;
for(i=0;i<24;i++)
{
memset(&key[i],i,1);
}
for(i=0;i<8;i++)
{
memset(&iv[i],i,1);
}
for(i=0;i<100;i++)
{
memset(&in[i],i,1);
}
EVP_CIPHER_CTX_init(&ctx);
printf("please select :\n");
printf("1: EVP_des_ede3_ofb\n");
printf("2: EVP_des_ede3_cbc\n");
scanf("%d",&which);
if(which==1)
cipher=EVP_des_ede3_ofb();
else
cipher=EVP_des_ede3_cbc();
ret=EVP_EncryptInit_ex(&ctx,cipher,NULL,key,iv);
if(ret!=1)
{
printf("EVP_EncryptInit_ex err1!\n");
return -1;
}
inl=50;
len=0;
EVP_EncryptUpdate(&ctx,out+len,&outl,in,inl);
len+=outl;
EVP_EncryptUpdate(&ctx,out+len,&outl,in+50,inl);
len+=outl;
EVP_EncryptFinal_ex(&ctx,out+len,&outl);
len+=outl;
printf("加密结果长度:%d\n",len);
/* 解密 */
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_init(&ctx);
ret=EVP_DecryptInit_ex(&ctx,cipher,NULL,key,iv);
if(ret!=1)
{
printf("EVP_DecryptInit_ex err1!\n");
return -1;
}
total=0;
EVP_DecryptUpdate(&ctx,de+total,&outl,out,44);
total+=outl;
EVP_DecryptUpdate(&ctx,de+total,&outl,out+44,len-44);
total+=outl;
ret=EVP_DecryptFinal_ex(&ctx,de+total,&outl);
total+=outl;
if(ret!=1)
{
EVP_CIPHER_CTX_cleanup(&ctx);
printf("EVP_DecryptFinal_ex err\n");
return -1;
}
if((total!=100) || (memcmp(de,in,100)))
{
printf("err!\n");
return -1;
}
EVP_CIPHER_CTX_cleanup(&ctx);
printf("test ok!\n");
return 0;
}
输出结果如下:
please select :
1: EVP_des_ede3_ofb
2: EVP_des_ede3_cbc
1
加密结果长度:100
test ok!
please select :
1: EVP_des_ede3_ofb
2: EVP_des_ede3_cbc
2
加密结果长度:104
test ok!
2)示例2
#include <string.h>
#include <openssl/evp.h>
int main()
{
int cnid,ret,i,msize,mtype;
int mpktype,cbsize,mnid,mbsize;
const EVP_CIPHER *type;
const EVP_MD *md;
int datal,count,keyl,ivl;
unsigned char salt[20],data[100],*key,*iv;
const char *cname,*mname;
type=EVP_des_ecb();
cnid=EVP_CIPHER_nid(type);
cname=EVP_CIPHER_name(type);
cbsize=EVP_CIPHER_block_size(type);
printf("encrypto nid : %d\n",cnid);
printf("encrypto name: %s\n",cname);
printf("encrypto bock size : %d\n",cbsize);
md=EVP_md5();
mtype=EVP_MD_type(md);
mnid=EVP_MD_nid(md);
mname=EVP_MD_name(md);
mpktype=EVP_MD_pkey_type(md);
msize=EVP_MD_size(md);
mbsize=EVP_MD_block_size(md);
printf("md info : \n");
printf("md type : %d\n",mtype);
printf("md nid : %d\n",mnid);
printf("md name : %s\n",mname);
printf("md pkey type : %d\n",mpktype);
printf("md size : %d\n",msize);
printf("md block size : %d\n",mbsize);
keyl=EVP_CIPHER_key_length(type);
key=(unsigned char *)malloc(keyl);
ivl=EVP_CIPHER_iv_length(type);
iv=(unsigned char *)malloc(ivl);
for(i=0;i<100;i++)
memset(&data[i],i,1);
for(i=0;i<20;i++)
memset(&salt[i],i,1);
datal=100;
count=2;
ret=EVP_BytesToKey(type,md,salt,data,datal,count,key,iv);
printf("generate key value: \n");
for(i=0;i<keyl;i++)
printf("%x ",*(key+i));
printf("\n");
printf("generate iv value: \n");
for(i=0;i<ivl;i++)
printf("%x ",*(iv+i));
printf("\n");
return 0;
}
EVP_BytesToKey函数通过salt以及data数据来生成所需要的key和iv。
输出:
encrypto nid : 29
encrypto name: DES-ECB
encrypto bock size : 8
md info :
md type : 4
md nid : 4
md name : MD5
md pkey type : 8
md size : 16
md block size : 64
generate key value:
54 0 b1 24 18 42 8d dd
generate iv value:
ba
7d c3
3) 示例3
#include <openssl/evp.h>
#include <openssl/rsa.h>
int main()
{
int ret,inlen,outlen=0;
unsigned long e=RSA_3;
char data[100],out[500];
EVP_MD_CTX md_ctx,md_ctx2;
EVP_PKEY *pkey;
RSA *rkey;
BIGNUM *bne;
/* 待签名数据*/
strcpy(data,"openssl 编程作者:赵春平");
inlen=strlen(data);
/* 生成RSA密钥*/
bne=BN_new();
ret=BN_set_word(bne,e);
rkey=RSA_new();
ret=RSA_generate_key_ex(rkey,1024,bne,NULL);
if(ret!=1) goto err;
pkey=EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey,rkey);
/* 初始化*/
EVP_MD_CTX_init(&md_ctx);
ret=EVP_SignInit_ex(&md_ctx,EVP_md5(), NULL);
if(ret!=1)goto err;
ret=EVP_SignUpdate(&md_ctx,data,inlen);
if(ret!=1)goto err;
ret=EVP_SignFinal(&md_ctx,out,&outlen,pkey);
/* 验证签名*/
EVP_MD_CTX_init(&md_ctx2);
ret=EVP_VerifyInit_ex(&md_ctx2,EVP_md5(), NULL);
if(ret!=1) goto err;
ret=EVP_VerifyUpdate(&md_ctx2,data,inlen);
if(ret!=1) goto err;
ret=EVP_VerifyFinal(&md_ctx2,out,outlen,pkey);
if(ret==1)
printf("验证成功\n");
else
printf("验证错误\n");
err:
RSA_free(rkey);
BN_free(bne);
return 0;
}
4)示例4
#include <openssl/evp.h>
#include <openssl/rsa.h>
int main()
{
int ret,ekl[2],npubk,inl,outl,total=0,total2=0;
unsigned long e=RSA_3;
char *ek[2],iv[8],in[100],out[500],de[500];
EVP_CIPHER_CTX ctx,ctx2;
EVP_CIPHER *type;
EVP_PKEY *pubkey[2];
RSA *rkey;
BIGNUM *bne;
/* 生成RSA密钥*/
bne=BN_new();
ret=BN_set_word(bne,e);
rkey=RSA_new();
ret=RSA_generate_key_ex(rkey,1024,bne,NULL);
pubkey[0]=EVP_PKEY_new();
EVP_PKEY_assign_RSA(pubkey[0],rkey);
type=EVP_des_cbc();
npubk=1;
EVP_CIPHER_CTX_init(&ctx);
ek[0]=malloc(500);
ek[1]=malloc(500);
ret=EVP_SealInit(&ctx,type,ek,ekl,iv,pubkey,1); /* 只有一个公钥*/
if(ret!=1) goto err;
strcpy(in,"openssl 编程");
inl=strlen(in);
ret=EVP_SealUpdate(&ctx,out,&outl,in,inl);
if(ret!=1)goto err;
total+=outl;
ret=EVP_SealFinal(&ctx,out+outl,&outl);
if(ret!=1) goto err;
total+=outl;
memset(de,0,500);
EVP_CIPHER_CTX_init(&ctx2);
ret=EVP_OpenInit(&ctx2,EVP_des_cbc(),ek[0],ekl[0],iv,pubkey[0]);
if(ret!=1) goto err;
ret=EVP_OpenUpdate(&ctx2,de,&outl,out,total);
total2+=outl;
ret=EVP_OpenFinal(&ctx2,de+outl,&outl);
total2+=outl;
de[total2]=0;
printf("%s\n",de);
err:
free(ek[0]);
free(ek[1]);
EVP_PKEY_free(pubkey[0]);
BN_free(bne);
getchar();
return 0;
}
输出结果:openssl 编程
参考文献:
[1] http://www.openssl.org/docs/crypto/evp.html#NAME