每一個可以努力的日子,都是一份厚禮。
AES加密和解密——使用openssl編程
AES是一套對稱密鑰的密碼術,目前已廣泛使用,用於替代已經不夠安全的DES算法。所謂對稱密鑰,就是說加密和解密用的是同一個密鑰,消息的發送方和接收方在消息傳遞前需要享有這個密鑰。和非對稱密鑰體系不同,這裡的密鑰是雙方保密的,不會讓任何第三方知道。
對稱密鑰加密法主要基於塊加密,選取固定長度的密鑰,去加密明文中固定長度的塊,生成的密文塊與明文塊長度一樣。顯然密鑰長度十分重要,塊的長度也很重要。如果太短,則很容易枚舉出所有的明文-密文映射;如果太長,性能則會急劇下降。AES中規定塊長度為128 bit,而密鑰長度可以選擇128, 192或256 bit 。暴力破解密鑰需要萬億年,這保證了AES的安全性。
AES的算法較為複雜,在此不細加闡述。下面是使用openssl進行AES加密和解密的示例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* * aes.cc * - Show the usage of AES encryption/decryption */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/aes.h> int main(int argc, char** argv) { AES_KEY aes; unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16 unsigned char iv[AES_BLOCK_SIZE]; // init vector unsigned char* input_string; unsigned char* encrypt_string; unsigned char* decrypt_string; unsigned int len; // encrypt length (in multiple of AES_BLOCK_SIZE) unsigned int i; // check usage if (argc != 2) { fprintf(stderr, "%s <plain text>\n", argv[0]); exit(-1); } // set the encryption length len = 0; if ((strlen(argv[1]) + 1) % AES_BLOCK_SIZE == 0) { len = strlen(argv[1]) + 1; } else { len = ((strlen(argv[1]) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE; } // set the input string input_string = (unsigned char*)calloc(len, sizeof(unsigned char)); if (input_string == NULL) { fprintf(stderr, "Unable to allocate memory for input_string\n"); exit(-1); } strncpy((char*)input_string, argv[1], strlen(argv[1])); // Generate AES 128-bit key for (i=0; i<16; ++i) { key[i] = 32 + i; } // Set encryption key for (i=0; i<AES_BLOCK_SIZE; ++i) { iv[i] = 0; } if (AES_set_encrypt_key(key, 128, &aes) < 0) { fprintf(stderr, "Unable to set encryption key in AES\n"); exit(-1); } // alloc encrypt_string encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char)); if (encrypt_string == NULL) { fprintf(stderr, "Unable to allocate memory for encrypt_string\n"); exit(-1); } // encrypt (iv will change) AES_cbc_encrypt(input_string, encrypt_string, len, &aes, iv, AES_ENCRYPT); // alloc decrypt_string decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char)); if (decrypt_string == NULL) { fprintf(stderr, "Unable to allocate memory for decrypt_string\n"); exit(-1); } // Set decryption key for (i=0; i<AES_BLOCK_SIZE; ++i) { iv[i] = 0; } if (AES_set_decrypt_key(key, 128, &aes) < 0) { fprintf(stderr, "Unable to set decryption key in AES\n"); exit(-1); } // decrypt AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv, AES_DECRYPT); // print printf("input_string = %s\n", input_string); printf("encrypted string = "); for (i=0; i<len; ++i) { printf("%x%x", (encrypt_string[i] >> 4) & 0xf, encrypt_string[i] & 0xf); } printf("\n"); printf("decrypted string = %s\n", decrypt_string); return 0; } |
編譯Makefile:
CC=g++ CFLAGS=-Wall -g -O2 LIBS=-lcrypto all: aes aes: aes.cc $(CC) $(CFLAGS) aes.cc -o $@ $(LIBS) clean: @rm -f aes |
這篇文章由lovelucy於2011-01-03 14:24發表在信息安全。你可以訂閱RSS 2.0 也可以發表評論或引用到你的網站。除特殊說明外文章均為本人原創,並遵從署名-非商業性使用-相同方式共享創作協議,轉載或使用請註明作者和來源,尊重知識分享。 |
批評不自由
則讚美無意義
Google Chrome 45.0.2454.101 Windows 7 大約8年前
你好,在解密時,調用AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv,AES_DECRYPT);解密時只收到需要解密的密文,請教一下,其中的參數:len怎麼計算,謝謝!