Gần đây tôi cuối cùng (với sự trợ giúp của người dùng stackoverflow, @WhozCraig) đã hoạt động AES ở chế độ CBC. Bây giờ, tôi muốn làm điều tương tự nhưng với AES IGE. Tôi đã xem openssl-1.0.1e/test/igetest.c
và cố gắng xây dựng thử nghiệm của riêng tôi. Nhưng một lần nữa, tôi có một vấn đề với đầu vào và đầu ra kích thước thích hợp. Mọi thứ khác là tốt, bởi vì tôi đã sao chép nó từ mã trước đây của tôi: AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C.Mã hóa/giải mã AES (aes-ige-128, aes-ige-192, age-ige-256) với openssl C
Bây giờ, khi tôi vượt qua một thời gian đầu vào đó là ít hơn 32 tuổi, nó nói:
Give a key length [only 128 or 192 or 256!]:
256
Give an input's length:
3
aes_ige.c(88): OpenSSL internal error, assertion failed: (length%AES_BLOCK_SIZE) == 0
(core dumped)
Nhưng khi chiều dài lớn hơn 32, Im cũng không như vậy chắc chắn nếu nó tất cả ok:
Give a key length [only 128 or 192 or 256!]:
256
Give an input's length:
48
original: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58
encrypt: A4 1F C4 E8 42 5E E5 62 1A B6 C1 47 D2 2F 8D 98 D0 0B 32 77 4E 36 84 25 15 5B BA 60 EA A9 64 D2 53 D1 98 78 83 21 90 90 74 44 C7 AA 3E AD 9B 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
decrypt: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58
Heres mã:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
const unsigned char * p = (const unsigned char*)pv;
if (NULL == pv)
printf("NULL");
else
{
size_t i = 0;
for (; i<len;++i)
printf("%02X ", *p++);
}
printf("\n");
}
// main entrypoint
int main(int argc, char **argv)
{
int keylength;
printf("Give a key length [only 128 or 192 or 256!]:\n");
scanf("%d", &keylength);
/* generate a key with a given length */
unsigned char aes_key[keylength/8];
memset(aes_key, 0, keylength/8);
if (!RAND_bytes(aes_key, keylength/8))
exit(-1);
size_t inputslength = 0;
printf("Give an input's length:\n");
scanf("%lu", &inputslength);
/* generate input with a given length */
unsigned char aes_input[inputslength];
memset(aes_input, 'X', inputslength);
const size_t ivsize = AES_BLOCK_SIZE*2;
/* init vector */
unsigned char iv_enc[ivsize], iv_dec[ivsize];
RAND_bytes(iv_enc, ivsize);
memcpy(iv_dec, iv_enc, ivsize);
// buffers for encryption and decryption
const size_t encslength = (inputslength/AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;//((inputslength + AES_BLOCK_SIZE)/AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_set_decrypt_key(aes_key, keylength, &dec_key);
AES_ige_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);
AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);
printf("original:\t");
hex_print(aes_input, sizeof(aes_input));
printf("encrypt:\t");
hex_print(enc_out, sizeof(enc_out));
printf("decrypt:\t");
hex_print(dec_out, sizeof(dec_out));
return 0;
}
CUỐI CÙNG! Chấn nó làm việc (hy vọng như vậy) .Nhưng tôi sẽ veeery biết ơn nếu ai đó có thể nói, rằng mã này dưới đây là 100% tốt;)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
const unsigned char * p = (const unsigned char*)pv;
if (NULL == pv)
printf("NULL");
else
{
size_t i = 0;
for (; i<len;++i)
printf("%02X ", *p++);
}
printf("\n");
}
// main entrypoint
int main(int argc, char **argv)
{
int keylength = 256;
//printf("Give a key length [only 128 or 192 or 256!]:\n");
//scanf("%d", &keylength);
/* generate a key with a given length */
unsigned char aes_key[keylength/8];
memset(aes_key, 0, keylength/8);
if (!RAND_bytes(aes_key, keylength/8))
exit(-1);
size_t inputslength = 0;
printf("Give an input's length:\n");
scanf("%lu", &inputslength);
/* generate input with a given length */
unsigned char aes_input[inputslength];
memset(aes_input, 'X', inputslength);
const size_t ivsize = AES_BLOCK_SIZE*2;
/* init vector */
unsigned char iv_enc[ivsize], iv_dec[ivsize];
RAND_bytes(iv_enc, ivsize);
memcpy(iv_dec, iv_enc, ivsize);
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE)/AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
// so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_ige_encrypt(aes_input, enc_out, encslength, &enc_key, iv_enc, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, keylength, &dec_key);
AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);
printf("original:\t");
hex_print(aes_input, sizeof(aes_input));
printf("encrypt:\t");
hex_print(enc_out, sizeof(enc_out));
printf("decrypt:\t");
hex_print(dec_out, sizeof(dec_out));
return 0;
}
tôi chỉ thay đổi này:
AES_ige_encrypt(aes_input, enc_out, **inputslength**, &enc_key, iv_enc, AES_ENCRYPT);
vào rằng:
AES_ige_encrypt(aes_input, enc_out, **encslength**, &enc_key, iv_enc, AES_ENCRYPT);
là nó có đúng không?
EDIT số 2;)
kẻ Ok, đã làm một ví dụ khác, với lời khuyên của bạn thêm một số đệm đầu vào. Hy vọng ok của nó bây giờ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
const unsigned char * p = (const unsigned char*)pv;
if (NULL == pv)
printf("NULL");
else
{
size_t i = 0;
for (; i<len;++i)
printf("%02X ", *p++);
}
printf("\n");
}
// main entrypoint
int main(int argc, char **argv)
{
int keylength = 256;
//printf("Give a key length [only 128 or 192 or 256!]:\n");
//scanf("%d", &keylength);
/* generate a key with a given length */
unsigned char aes_key[keylength/8];
memset(aes_key, 0, keylength/8);
if (!RAND_bytes(aes_key, keylength/8))
exit(-1);
size_t inputslength = 0;
printf("Give an input's length:\n");
scanf("%lu", &inputslength);
/* generate input with a given length */
unsigned char aes_input[inputslength];
memset(aes_input, 'X', inputslength);
const size_t ivsize = AES_BLOCK_SIZE*2;
/* init vector */
unsigned char iv_enc[ivsize], iv_dec[ivsize];
RAND_bytes(iv_enc, ivsize);
memcpy(iv_dec, iv_enc, ivsize);
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE)/AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char paddedinput[encslength];
memset(paddedinput, 0, encslength);
memcpy(paddedinput, aes_input, inputslength);
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_ige_encrypt(paddedinput, enc_out, encslength, &enc_key, iv_enc, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, keylength, &dec_key);
AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);
printf("original:\t");
hex_print(aes_input, sizeof(aes_input));
printf("encrypt:\t");
hex_print(enc_out, sizeof(enc_out));
printf("decrypt:\t");
hex_print(dec_out, sizeof(dec_out));
return 0;
}
@WhozCraig: tôi có thể làm phiền bạn thêm một chút nữa không? Bạn có thể vui lòng nhìn vào mã thứ hai của tôi tôi dán ở đây và chỉ nói nếu nó đúng hay không? Vấn đề chính tôi có với 'AES_ige_encrypt' - khi tôi truyền' inputlength' thay vì 'encslength', tôi gặp lỗi lạ:' aes_ige.c (88): Lỗi nội bộ OpenSSL, xác nhận không thành công: (length% AES_BLOCK_SIZE) == 0 ' – ivy
Nếu bạn không thực hiện bất kỳ padding (padding zero hoặc cách khác) thì bạn cần văn bản thuần của bạn chính xác N lần kích thước khối. Phần nào của điều này không rõ ràng với bạn? IGE cũng giống như CBC trong vấn đề đó. –
@owlstead: Cảm ơn câu trả lời. Yup, tôi đọc rất nhiều về nó ngày hôm qua và tôi nghĩ rõ ràng với tôi bây giờ. Nhưng chỉ có một điều nữa tôi không thể hiểu được. Trong [mã trước đó] của tôi (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c) I đã không làm bất kỳ padding, và nó đã được tất cả tốt. Tôi có nghĩa là, tôi đã thông qua để 'AES_cbc_encrypt' một đầu vào với chiều dài được đưa ra bởi người sử dụng (không có một padding!), Vì vậy, tại sao bây giờ nó không hoạt động? – ivy