利用OpenSSL中EVP封装调用对称加密算法的通用代码

http://blog.csdn.net/force_eagle/archive/2009/07/10/4337768.aspx

 

原创   利用OpenSSL中EVP封装调用对称加密算法的通用代码 收藏

Code:

 

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <openssl/evp.h>   
  5.   
  6. #ifdef _MSC_VER   
  7. #pragma  comment(lib,"libeay32.lib")   
  8. typedef  unsigned  char  uint8_t;  
  9. #define bzero(a, b) memset( a, 0x0, b )   
  10. #else   
  11. #include <stdint.h>   
  12. #endif   
  13.   
  14. // {EA6E74BD-1A25-4b06-8493-B0F9319BD3B9}   
  15. static   const  uint8_t ks_des_ede3[] = {  
  16.     0xea, 0x6e, 0x74, 0xbd, 0x1a, 0x25, 0x4b, 0x06,   
  17.     0x84, 0x93, 0xb0, 0xf9, 0x31, 0x9b, 0xd3, 0xb9,  
  18.     0x9b, 0xc3, 0x25, 0xa4, 0x7f, 0x43, 0xa0, 0x44  
  19. };  
  20.   
  21. // {73243D40-FFFD-47fe-87A3-3A1E0DABCAC7}   
  22. static   const  uint8_t ks_aes_128[] = {   
  23.     0x73, 0x24, 0x3d, 0x40, 0xff, 0xfd, 0x47, 0xfe,   
  24.     0x87, 0xa3, 0x3a, 0x1e, 0x0d, 0xab, 0xca, 0xc7   
  25. };  
  26. // {2D89EA6D-1F3C-4b47-AA27-5F6B78800874}   
  27. static   const  uint8_t ks_aes_192[] = {   
  28.     0x2d, 0x89, 0xea, 0x6d, 0x1f, 0x3c, 0x4b, 0x47,  
  29.     0xaa, 0x27, 0x5f, 0x6b, 0x78, 0x80, 0x08, 0x74,  
  30.     0x8b, 0x57, 0x7b, 0x84, 0x45, 0x8f, 0xe1, 0x7d  
  31. };  
  32.   
  33. // {C20A94E8-601F-409d-B957-33A0E539C20A}   
  34. static   const  uint8_t ks_aes_256[] = {   
  35.     0xc2, 0x0a, 0x94, 0xe8, 0x60, 0x1f, 0x40, 0x9d,   
  36.     0xb9, 0x57, 0x33, 0xa0, 0xe5, 0x39, 0xc2, 0x0a,  
  37.     0x0f, 0xe3, 0x39, 0xdd, 0x5c, 0x02, 0x4f, 0x11,   
  38.     0x96, 0x67, 0xd5, 0x4d, 0x4d, 0xe8, 0xb1, 0x3c   
  39. };  
  40.   
  41. // 典型的加密算法密钥长度(byte)   
  42. #define DES_KEY_LENGTH      8   
  43. #define DES_EDE_KEY_LENGTH  16   
  44. #define DES_EDE3_KEY_LENGTH 24   
  45.   
  46. #define AES_128_KEY_LENGTH  16   
  47. #define AES_192_KEY_LENGTH  24   
  48. #define AES_256_KEY_LENGTH  32   
  49.   
  50.   
  51. /*=============================================================================*/   
  52. //  Function name   : cipher_dump   
  53. //  Description     : dump cipher infomation   
  54. //  Input           :    
  55. //                    const EVP_CIPHER * ctx   
  56. //  Return type     : void  none    
  57. /*=============================================================================*/   
  58. void  cipher_dump( const  EVP_CIPHER * ctx)  
  59. {  
  60.     //EVP_CIPHER_CTX_cipher()    
  61.     int  key_len = EVP_CIPHER_key_length( ctx );  
  62.     int  block_size = EVP_CIPHER_block_size( ctx );  
  63.     int  iv_len = EVP_CIPHER_iv_length( ctx );  
  64.     int  type = EVP_CIPHER_type(ctx );  
  65.     int  mode = EVP_CIPHER_mode( ctx );  
  66.     int  nid = EVP_CIPHER_nid( ctx );  
  67.   
  68.     printf( "=====================================/n"  );  
  69.     printf( "key length=%d /n" , key_len );  
  70.     printf( "block size=%d /n" , block_size );  
  71.     printf( "iv length=%d /n" , iv_len );  
  72.     printf( "type=%d /n" , type );  
  73.     printf( "mode=%d /n" , mode );  
  74.     printf( "nid=%d /n" , nid );  
  75. }  
  76.   
  77.   
  78. /*=============================================================================*/   
  79. //  Function name   : calc_cipher_length   
  80. //  Description     : calc cipher text length   
  81. //  Input           :    
  82. //                    EVP_CIPHER_CTX * ctx   
  83. //                    int inlen   
  84. //  Return type     : int return cipher text length    
  85. /*=============================================================================*/   
  86. int  calc_cipher_length(EVP_CIPHER_CTX * ctx, int  inlen)  
  87. {  
  88.     int  block_size = EVP_CIPHER_CTX_block_size( ctx );  
  89.     int  block_cnt = 0;  
  90.     int  block_final = 0;  
  91.     int  cipher_length = 0;  
  92.   
  93.     if  ( inlen < block_size ) {  
  94.         printf( "calc cipher length = %d/n" , block_size );  
  95.         return  block_size;  
  96.     }  
  97.   
  98.     block_cnt = inlen / block_size;  
  99.     cipher_length = block_cnt * block_size;  
  100.   
  101.     block_final = inlen - cipher_length;  
  102.     if  ( block_final >= 0 ) {  
  103.         block_final = block_size;  
  104.     }  
  105.     cipher_length += block_final;  
  106.     printf( "calc cipher length = %d/n" , cipher_length );  
  107.     return  cipher_length;  
  108. }  
  109. /*=============================================================================*/   
  110. //  Function name   : do_crypt   
  111. //  Description     : 使用3DES 加解 密数据   
  112. //  Input           :    
  113. //                    uint8_t *in       输 入数据缓冲   
  114. //                    int inlen         输入数据长度   
  115. //                    uint8_t **out     输 出数据缓冲指针   
  116. //                    int *outlen       输出数据长度   
  117. //                    int do_encrypt    加 解密标志(1:加密; 0:解密)   
  118. //  Return type     : int   success return 0 or return -1     
  119. /*=============================================================================*/   
  120. int  do_crypt(uint8_t *in,  int  inlen, uint8_t **out,  int  *outlen,  int  do_encrypt )  
  121. {  
  122.     uint8_t *key = (uint8_t *)ks_des_ede3;  
  123.     int  len;  
  124.     EVP_CIPHER_CTX ctx;  
  125.     //uint8_t outbuf[1024 + EVP_MAX_BLOCK_LENGTH];   
  126.     uint8_t *outbuf = NULL;  
  127.     uint8_t *pb = NULL;  
  128.     int   retval = 0;  
  129.     int   cipher_length = 0;  
  130.   
  131.     if  ( inlen <= 0 || in == NULL ) {  
  132.         return  0;  
  133.     }  
  134.     EVP_CIPHER_CTX_init(&ctx);  
  135.     // 使用Triple DES   
  136.     retval = EVP_CipherInit(&ctx, EVP_des_ede3_cbc(), key, NULL, do_encrypt );  
  137.     // 计算输出缓冲长度   
  138.     if  ( do_encrypt ) {  
  139.         cipher_length = calc_cipher_length( &ctx, inlen );  
  140.         outbuf = (uint8_t *)malloc( cipher_length );  
  141.     }  
  142.     else  {  
  143.         outbuf = (uint8_t *)malloc( inlen );  
  144.     }  
  145.     pb = outbuf;  
  146.     // evp 调用加解密操作   
  147.     if  (!EVP_CipherUpdate(&ctx, pb, &len, in, inlen)) {  
  148.         /* Error */   
  149.         free( outbuf );  
  150.         EVP_CIPHER_CTX_cleanup(&ctx);  
  151.         return  0;  
  152.     }  
  153.   
  154.     *outlen = len;  
  155.     pb += len;  
  156.     len = 0;  
  157.   
  158.     if  (!EVP_CipherFinal(&ctx, pb,&len)) {  
  159.         /* Error */   
  160.         free( outbuf );  
  161.         EVP_CIPHER_CTX_cleanup(&ctx);  
  162.         return  0;  
  163.     }  
  164.   
  165.     *outlen += len;  
  166.   
  167.     pb = outbuf;  
  168.     // 如为解密则重新分配解密后数据大小缓冲   
  169.     if  ( !do_encrypt ) {          
  170.         if  ( inlen != ( *outlen ) ) {  
  171.             pb = (uint8_t *)malloc( *outlen );  
  172.             memcpy( pb, outbuf, *outlen );  
  173.             free( outbuf );  
  174.         }  
  175.     }  
  176.     *out= pb;  
  177.     EVP_CIPHER_CTX_cleanup(&ctx);  
  178.     return  1;  
  179. }  
  180.   
  181. int  main( int  argc,  char * argv[])  
  182. {  
  183.     /*  
  184.     OPENSSL_add_all_algorithms_noconf();  
  185.     OpenSSL_add_all_ciphers();  
  186.     OpenSSL_add_all_digests();  
  187.     */   
  188.     // 变换plain_text 大小分别 为 5, 8, 13, 16   
  189.     uint8_t plain_text[13] = { "test"  };  
  190.     uint8_t *cipher_text = NULL;  
  191.     uint8_t *out_text = NULL;  
  192.   
  193.     int  inlen = 0, outlen = 0;  
  194.     int  len = 0;  
  195.   
  196.     cipher_dump( EVP_des_ede3_cbc() );  
  197.     cipher_dump( EVP_aes_128_cfb128() );  
  198.     printf( "=============/n" );  
  199.     do_crypt( plain_text, sizeof ( plain_text), &cipher_text, &outlen, 1 );  
  200.     printf( "crypt out length = %d/n" , outlen  );  
  201.   
  202.     do_crypt( cipher_text, outlen, &out_text, &len, 0 );  
  203.     printf( "crypt out length = %d/n" , len  );  
  204.   
  205.     free( cipher_text );  
  206.     free( out_text );  
  207.     return  0;  
  208. }  

加密长度5bytes

  1. # gcc t3.c -o t3 -lssl   
  2. # ./t3   
  3. =====================================  
  4. key length=24  
  5. block size=8  
  6. iv length=8  
  7. type=44  
  8. mode=2  
  9. nid=44  
  10. =====================================  
  11. key length=16  
  12. block size=1  
  13. iv length=16  
  14. type=421  
  15. mode=3  
  16. nid=421  
  17. =============  
  18. calc cipher length = 8  
  19. crypt out  length = 8  
  20. crypt out  length = 5  

加密长度8bytes

  1. # gcc t3.c -o t3 -lssl   
  2. # ./t3   
  3. =====================================  
  4. key length=24  
  5. block size=8  
  6. iv length=8  
  7. type=44  
  8. mode=2  
  9. nid=44  
  10. =====================================  
  11. key length=16  
  12. block size=1  
  13. iv length=16  
  14. type=421  
  15. mode=3  
  16. nid=421  
  17. =============  
  18. calc cipher length = 16  
  19. crypt out length = 16  
  20. crypt out length = 8  

加密长度13bytes

  1. # gcc t3.c -o t3 -lssl   
  2. # ./t3   
  3. =====================================  
  4. key length=24  
  5. block size=8  
  6. iv length=8  
  7. type=44  
  8. mode=2  
  9. nid=44  
  10. =====================================  
  11. key length=16  
  12. block size=1  
  13. iv length=16  
  14. type=421  
  15. mode=3  
  16. nid=421  
  17. =============  
  18. calc cipher length = 16  
  19. crypt out length = 16  
  20. crypt out length = 13  

加密长度16bytes

  1. # gcc t3.c -o t3 -lssl   
  2. # ./t3   
  3. =====================================  
  4. key length=24  
  5. block size=8  
  6. iv length=8  
  7. type=44  
  8. mode=2  
  9. nid=44  
  10. =====================================  
  11. key length=16  
  12. block size=1  
  13. iv length=16  
  14. type=421  
  15. mode=3  
  16. nid=421  
  17. =============  
  18. calc cipher length = 24  
  19. crypt out length = 24  
  20. crypt out length = 16 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值