2013-08-11 46 views
5

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; 
} 
+1

@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

+2

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 đề đó. –

+0

@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

Trả lời

4

Thông báo lỗi nói tất cả.

aes_ige.c(88): OpenSSL internal error, assertion failed: (length%AES_BLOCK_SIZE) == 0 

này về cơ bản là một thời gian chạy kiểm tra (khẳng định) mà không do đầu vào không hợp lệ cung cấp cho các chức năng AES_ige_encrypt() hiện diện trong nguồn tại line 88 of aes_ige.c.

OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); 

Các khẳng định về cơ bản kiểm tra nếu length (tham số thứ 3 thông qua chức năng) là một bội số nguyên của AES_BLOCK_SIZE. Nếu có, thực hiện tiếp tục, nếu không chương trình sẽ dừng lại và in cảnh báo về xác nhận đã thất bại.

  1. Vì vậy, đảm bảo rằng kích thước của dữ liệu được truyền đến AES_ige_encrypt() là bội số của AES_BLOCK_SIZE.

  2. Nếu kích thước của dữ liệu không phải là một thiếu nhiều, sau đó nối NUL byte với nó để làm cho tổng kích thước bội số gần nhất của AES_BLOCK_SIZE.

  3. Ngoài ra, luôn luôn vượt qua "không thể thiếu-nhiều-of- AES_BLOCK_SIZE" giá trị như tham số length để AES_ige_encrypt().

+0

Cảm ơn bạn đã giải thích. Tôi biết lỗi đến từ đâu nhưng tôi không hiểu tại sao. 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 didnt làm bất kỳ padding, và nó đã làm việc. Tôi đã chuyển cho 'AES_cbc_encrypt' một đầu vào với chiều dài được đưa ra bởi người dùng (không có đệm!), Vậy tại sao nó không hoạt động? Tôi đã làm một mã ví dụ khác: http://pastie.org/private/yzlkcudvpwwfczvpvo8gw và có vẻ như bây giờ là ok. Bất kỳ ý tưởng tại sao tôi không thể làm tương tự như trước? – ivy

+0

Một câu hỏi khác;) Vì vậy, đối với mọi mật mã khối kích thước, tôi phải truyền một đầu vào là bội số của CIPHERs_BLOCK_SIZE? Điều đó có đúng với mật mã kích thước khối MỌI không? Cảm ơn :) – ivy

+4

Trước đó, khi bạn gọi [** 'AES_cbc_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/aes__cbc_8c_source.html#l00055), nó được gọi nội bộ [** 'CRYPTO_cbc128_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/cbc128_8c.html#a5cbe79f5b3a935a6e49ac72e3f3e4fb2) không có giới hạn về độ dài của dữ liệu tải trọng được mã hóa. Do đó bạn không nhận được bất kỳ lỗi nào. – TheCodeArtist

Các vấn đề liên quan