第二十一章 EVP / 21.10编程示例

       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数据来生成所需要的keyiv

       输出:

       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 97 a0 c9 e0 70

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