http://blog.csdn.net/force_eagle/archive/2009/07/10/4337768.aspx
利用OpenSSL中EVP封装调用对称加密算法的通用代码 收藏
Code:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <openssl/evp.h>
- #ifdef _MSC_VER
- #pragma comment(lib,"libeay32.lib")
- typedef unsigned char uint8_t;
- #define bzero(a, b) memset( a, 0x0, b )
- #else
- #include <stdint.h>
- #endif
- // {EA6E74BD-1A25-4b06-8493-B0F9319BD3B9}
- static const uint8_t ks_des_ede3[] = {
- 0xea, 0x6e, 0x74, 0xbd, 0x1a, 0x25, 0x4b, 0x06,
- 0x84, 0x93, 0xb0, 0xf9, 0x31, 0x9b, 0xd3, 0xb9,
- 0x9b, 0xc3, 0x25, 0xa4, 0x7f, 0x43, 0xa0, 0x44
- };
- // {73243D40-FFFD-47fe-87A3-3A1E0DABCAC7}
- static const uint8_t ks_aes_128[] = {
- 0x73, 0x24, 0x3d, 0x40, 0xff, 0xfd, 0x47, 0xfe,
- 0x87, 0xa3, 0x3a, 0x1e, 0x0d, 0xab, 0xca, 0xc7
- };
- // {2D89EA6D-1F3C-4b47-AA27-5F6B78800874}
- static const uint8_t ks_aes_192[] = {
- 0x2d, 0x89, 0xea, 0x6d, 0x1f, 0x3c, 0x4b, 0x47,
- 0xaa, 0x27, 0x5f, 0x6b, 0x78, 0x80, 0x08, 0x74,
- 0x8b, 0x57, 0x7b, 0x84, 0x45, 0x8f, 0xe1, 0x7d
- };
- // {C20A94E8-601F-409d-B957-33A0E539C20A}
- static const uint8_t ks_aes_256[] = {
- 0xc2, 0x0a, 0x94, 0xe8, 0x60, 0x1f, 0x40, 0x9d,
- 0xb9, 0x57, 0x33, 0xa0, 0xe5, 0x39, 0xc2, 0x0a,
- 0x0f, 0xe3, 0x39, 0xdd, 0x5c, 0x02, 0x4f, 0x11,
- 0x96, 0x67, 0xd5, 0x4d, 0x4d, 0xe8, 0xb1, 0x3c
- };
- // 典型的加密算法密钥长度(byte)
- #define DES_KEY_LENGTH 8
- #define DES_EDE_KEY_LENGTH 16
- #define DES_EDE3_KEY_LENGTH 24
- #define AES_128_KEY_LENGTH 16
- #define AES_192_KEY_LENGTH 24
- #define AES_256_KEY_LENGTH 32
- /*=============================================================================*/
- // Function name : cipher_dump
- // Description : dump cipher infomation
- // Input :
- // const EVP_CIPHER * ctx
- // Return type : void none
- /*=============================================================================*/
- void cipher_dump( const EVP_CIPHER * ctx)
- {
- //EVP_CIPHER_CTX_cipher()
- int key_len = EVP_CIPHER_key_length( ctx );
- int block_size = EVP_CIPHER_block_size( ctx );
- int iv_len = EVP_CIPHER_iv_length( ctx );
- int type = EVP_CIPHER_type(ctx );
- int mode = EVP_CIPHER_mode( ctx );
- int nid = EVP_CIPHER_nid( ctx );
- printf( "=====================================/n" );
- printf( "key length=%d /n" , key_len );
- printf( "block size=%d /n" , block_size );
- printf( "iv length=%d /n" , iv_len );
- printf( "type=%d /n" , type );
- printf( "mode=%d /n" , mode );
- printf( "nid=%d /n" , nid );
- }
- /*=============================================================================*/
- // Function name : calc_cipher_length
- // Description : calc cipher text length
- // Input :
- // EVP_CIPHER_CTX * ctx
- // int inlen
- // Return type : int return cipher text length
- /*=============================================================================*/
- int calc_cipher_length(EVP_CIPHER_CTX * ctx, int inlen)
- {
- int block_size = EVP_CIPHER_CTX_block_size( ctx );
- int block_cnt = 0;
- int block_final = 0;
- int cipher_length = 0;
- if ( inlen < block_size ) {
- printf( "calc cipher length = %d/n" , block_size );
- return block_size;
- }
- block_cnt = inlen / block_size;
- cipher_length = block_cnt * block_size;
- block_final = inlen - cipher_length;
- if ( block_final >= 0 ) {
- block_final = block_size;
- }
- cipher_length += block_final;
- printf( "calc cipher length = %d/n" , cipher_length );
- return cipher_length;
- }
- /*=============================================================================*/
- // Function name : do_crypt
- // Description : 使用3DES 加解 密数据
- // Input :
- // uint8_t *in 输 入数据缓冲
- // int inlen 输入数据长度
- // uint8_t **out 输 出数据缓冲指针
- // int *outlen 输出数据长度
- // int do_encrypt 加 解密标志(1:加密; 0:解密)
- // Return type : int success return 0 or return -1
- /*=============================================================================*/
- int do_crypt(uint8_t *in, int inlen, uint8_t **out, int *outlen, int do_encrypt )
- {
- uint8_t *key = (uint8_t *)ks_des_ede3;
- int len;
- EVP_CIPHER_CTX ctx;
- //uint8_t outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
- uint8_t *outbuf = NULL;
- uint8_t *pb = NULL;
- int retval = 0;
- int cipher_length = 0;
- if ( inlen <= 0 || in == NULL ) {
- return 0;
- }
- EVP_CIPHER_CTX_init(&ctx);
- // 使用Triple DES
- retval = EVP_CipherInit(&ctx, EVP_des_ede3_cbc(), key, NULL, do_encrypt );
- // 计算输出缓冲长度
- if ( do_encrypt ) {
- cipher_length = calc_cipher_length( &ctx, inlen );
- outbuf = (uint8_t *)malloc( cipher_length );
- }
- else {
- outbuf = (uint8_t *)malloc( inlen );
- }
- pb = outbuf;
- // evp 调用加解密操作
- if (!EVP_CipherUpdate(&ctx, pb, &len, in, inlen)) {
- /* Error */
- free( outbuf );
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 0;
- }
- *outlen = len;
- pb += len;
- len = 0;
- if (!EVP_CipherFinal(&ctx, pb,&len)) {
- /* Error */
- free( outbuf );
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 0;
- }
- *outlen += len;
- pb = outbuf;
- // 如为解密则重新分配解密后数据大小缓冲
- if ( !do_encrypt ) {
- if ( inlen != ( *outlen ) ) {
- pb = (uint8_t *)malloc( *outlen );
- memcpy( pb, outbuf, *outlen );
- free( outbuf );
- }
- }
- *out= pb;
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 1;
- }
- int main( int argc, char * argv[])
- {
- /*
- OPENSSL_add_all_algorithms_noconf();
- OpenSSL_add_all_ciphers();
- OpenSSL_add_all_digests();
- */
- // 变换plain_text 大小分别 为 5, 8, 13, 16
- uint8_t plain_text[13] = { "test" };
- uint8_t *cipher_text = NULL;
- uint8_t *out_text = NULL;
- int inlen = 0, outlen = 0;
- int len = 0;
- cipher_dump( EVP_des_ede3_cbc() );
- cipher_dump( EVP_aes_128_cfb128() );
- printf( "=============/n" );
- do_crypt( plain_text, sizeof ( plain_text), &cipher_text, &outlen, 1 );
- printf( "crypt out length = %d/n" , outlen );
- do_crypt( cipher_text, outlen, &out_text, &len, 0 );
- printf( "crypt out length = %d/n" , len );
- free( cipher_text );
- free( out_text );
- return 0;
- }
加密长度5bytes
- # gcc t3.c -o t3 -lssl
- # ./t3
- =====================================
- key length=24
- block size=8
- iv length=8
- type=44
- mode=2
- nid=44
- =====================================
- key length=16
- block size=1
- iv length=16
- type=421
- mode=3
- nid=421
- =============
- calc cipher length = 8
- crypt out length = 8
- crypt out length = 5
加密长度8bytes
- # gcc t3.c -o t3 -lssl
- # ./t3
- =====================================
- key length=24
- block size=8
- iv length=8
- type=44
- mode=2
- nid=44
- =====================================
- key length=16
- block size=1
- iv length=16
- type=421
- mode=3
- nid=421
- =============
- calc cipher length = 16
- crypt out length = 16
- crypt out length = 8
加密长度13bytes
- # gcc t3.c -o t3 -lssl
- # ./t3
- =====================================
- key length=24
- block size=8
- iv length=8
- type=44
- mode=2
- nid=44
- =====================================
- key length=16
- block size=1
- iv length=16
- type=421
- mode=3
- nid=421
- =============
- calc cipher length = 16
- crypt out length = 16
- crypt out length = 13
加密长度16bytes
- # gcc t3.c -o t3 -lssl
- # ./t3
- =====================================
- key length=24
- block size=8
- iv length=8
- type=44
- mode=2
- nid=44
- =====================================
- key length=16
- block size=1
- iv length=16
- type=421
- mode=3
- nid=421
- =============
- calc cipher length = 24
- crypt out length = 24
- crypt out length = 16