AES加密和解密(使用openssl编程)

时间:2021-11-17 18:31:39

from: http://www.lovelucy.info/openssl-aes-encryption.html


AES是一套对称密钥的密码术,目前已广泛使用,用于替代已经不够安全的DES算法。所谓对称密钥,就是说加密和解密用的是同一个密钥,消息的发送方和接收方在消息传递前需要享有这个密钥。和非对称密钥体系不同,这里的密钥是双方保密的,不会让任何第三方知道。

对称密钥加密法主要基于块加密,选取固定长度的密钥,去加密明文中固定长度的块,生成的密文块与明文块长度一样。显然密钥长度十分重要,块的长度也很重要。如果太短,则很容易枚举出所有的明文-密文映射;如果太长,性能则会急剧下降。AES中规定块长度为128 bit,而密钥长度可以选择128, 192或256 bit 。暴力破解密钥需要万亿年,这保证了AES的安全性。

AES的算法较为复杂,在此不细加阐述。下面是使用openssl进行AES加密和解密的示例程序:

[cpp] view plain copy
  1. /* 
  2. * aes.cc 
  3. * - Show the usage of AES encryption/decryption 
  4. */  
  5.    
  6. #include <stdio.h>  
  7. #include <string.h>  
  8. #include <stdlib.h>  
  9. #include <openssl/aes.h>  
  10.    
  11. int main(int argc, char** argv) {  
  12.     AES_KEY aes;  
  13.     unsigned char key[AES_BLOCK_SIZE];        // AES_BLOCK_SIZE = 16  
  14.     unsigned char iv[AES_BLOCK_SIZE];        // init vector  
  15.     unsigned char* input_string;  
  16.     unsigned char* encrypt_string;  
  17.     unsigned char* decrypt_string;  
  18.     unsigned int len;        // encrypt length (in multiple of AES_BLOCK_SIZE)  
  19.     unsigned int i;  
  20.    
  21.     // check usage  
  22.     if (argc != 2) {  
  23.         fprintf(stderr, "%s <plain text>\n", argv[0]);  
  24.         exit(-1);  
  25.     }  
  26.    
  27.     // set the encryption length  
  28.     len = 0;  
  29.     if ((strlen(argv[1]) + 1) % AES_BLOCK_SIZE == 0) {  
  30.         len = strlen(argv[1]) + 1;  
  31.     } else {  
  32.         len = ((strlen(argv[1]) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;  
  33.     }  
  34.    
  35.     // set the input string  
  36.     input_string = (unsigned char*)calloc(len, sizeof(unsigned char));  
  37.     if (input_string == NULL) {  
  38.         fprintf(stderr, "Unable to allocate memory for input_string\n");  
  39.         exit(-1);  
  40.     }  
  41.     strncpy((char*)input_string, argv[1], strlen(argv[1]));  
  42.    
  43.     // Generate AES 128-bit key  
  44.     for (i=0; i<16; ++i) {  
  45.         key[i] = 32 + i;  
  46.     }  
  47.    
  48.     // Set encryption key  
  49.     for (i=0; i<AES_BLOCK_SIZE; ++i) {  
  50.         iv[i] = 0;  
  51.     }  
  52.     if (AES_set_encrypt_key(key, 128, &aes) < 0) {  
  53.         fprintf(stderr, "Unable to set encryption key in AES\n");  
  54.         exit(-1);  
  55.     }  
  56.    
  57.     // alloc encrypt_string  
  58.     encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));      
  59.     if (encrypt_string == NULL) {  
  60.         fprintf(stderr, "Unable to allocate memory for encrypt_string\n");  
  61.         exit(-1);  
  62.     }  
  63.    
  64.     // encrypt (iv will change)  
  65.     AES_cbc_encrypt(input_string, encrypt_string, len, &aes, iv, AES_ENCRYPT);  
  66.    
  67.     // alloc decrypt_string  
  68.     decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));  
  69.     if (decrypt_string == NULL) {  
  70.         fprintf(stderr, "Unable to allocate memory for decrypt_string\n");  
  71.         exit(-1);  
  72.     }  
  73.    
  74.     // Set decryption key  
  75.     for (i=0; i<AES_BLOCK_SIZE; ++i) {  
  76.         iv[i] = 0;  
  77.     }  
  78.     if (AES_set_decrypt_key(key, 128, &aes) < 0) {  
  79.         fprintf(stderr, "Unable to set decryption key in AES\n");  
  80.         exit(-1);  
  81.     }  
  82.    
  83.     // decrypt  
  84.     AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv,   
  85.             AES_DECRYPT);  
  86.    
  87.     // print  
  88.     printf("input_string = %s\n", input_string);  
  89.     printf("encrypted string = ");  
  90.     for (i=0; i<len; ++i) {  
  91.         printf("%x%x", (encrypt_string[i] >> 4) & 0xf,   
  92.                 encrypt_string[i] & 0xf);      
  93.     }  
  94.     printf("\n");  
  95.     printf("decrypted string = %s\n", decrypt_string);  
  96.    
  97.     return 0;  
  98. }  

编译Makefile:
[plain] view plain copy
  1. CC=g++  
  2. CFLAGS=-Wall -g -O2  
  3. LIBS=-lcrypto  
  4.    
  5. all: aes  
  6.    
  7. aes: aes.cc  
  8.     $(CC) $(CFLAGS) aes.cc -o $@ $(LIBS)  
  9.    
  10. clean:  
  11.     @rm -f aes