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