2013-08-11 15 views
5

Ostatnio w końcu (przy pomocy użytkownika stackoverflow, @WhozCraig) udało się pracować AES w trybie CBC. Teraz chciałbym zrobić dokładnie to samo, ale z AES IGE. Przyjrzałem się openssl-1.0.1e/test/igetest.c i próbowałem zbudować własny test. Ale po raz kolejny mam problem z wejściami i wyjściami o odpowiednich rozmiarach. Wszystko inne jest dobre, ponieważ skopiowałem go z mojego poprzedniego kodu: AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C.AES (aes-ige-128, aes-ige-192, aes-ige-256) szyfrowanie/deszyfrowanie z openssl C

Teraz, kiedy przekazać wejścia długość, która jest mniejsza niż 32, to mówi:

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) 

Ale gdy długość jest większa niż 32, Im również nie tak pewny jeśli jej wszystko 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 

Herezje kod:

#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; 
} 

WRESZCIE! Ale to działa (mam nadzieję) .Ale będę baaardzo wdzięczny jeśli ktoś może powiedzieć, że ten kod jest poniżej 100% dobry;)

#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; 
} 

tylko zmieniłem to:

AES_ige_encrypt(aes_input, enc_out, **inputslength**, &enc_key, iv_enc, AES_ENCRYPT);

się, że:

AES_ige_encrypt(aes_input, enc_out, **encslength**, &enc_key, iv_enc, AES_ENCRYPT);

jest to prawidłowe?

EDIT nr.2;)

Ok chłopaki, zrobił kolejny przykład, ze swoimi porady dodano kilka dopełnienie do wejścia. Mam nadzieję, że teraz jest ok?

#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: czy mogę przez jakiś czas zawracać ci głowę? Czy mógłbyś popatrzeć na mój drugi kod, który wkleiłem tutaj i powiedzieć tylko, czy jest poprawny czy nie? Główny problem jaki mam z 'AES_ige_encrypt' - kiedy przekazuję' inputslength' zamiast 'encslength', mam dziwny błąd:' aes_ige.c (88): Błąd wewnętrzny OpenSSL, asercja nie powiodła się: (length% AES_BLOCK_SIZE) == 0 ' – ivy

+2

Jeśli nie wykonujesz wypełnienia (wyładowanie w bajtach zerowych lub w inny sposób), musisz mieć zwykły tekst dokładnie N razy większy od rozmiaru bloku. Jaka część tego nie jest dla ciebie jasna? IGE jest taka sama jak CBC w tej sprawie. –

+0

@owlstead: Dzięki za odpowiedź. Tak, dużo czytałem wczoraj i myślę, że teraz jest dla mnie jasne. Ale jest jeszcze jedna rzecz, której naprawdę nie mogę zrozumieć. W moim [poprzednim kodzie] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc256-encryption-decryption-with-openssl-c) I nie zrobiłem żadnej wyściółki i wszystko było dobrze. Mam na myśli, przekazałem do 'AES_cbc_encrypt' dane wejściowe o długości podanej przez użytkownika (bez dopełnienia!), Więc dlaczego teraz nie działa? – ivy

Odpowiedz

4

Komunikat błąd mówi wszystko.

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

Jest to po prostu run-time-check (twierdzenie), że nie powiedzie się z powodu nieprawidłowych danych dostarczonych do funkcji AES_ige_encrypt() obecnego w źródle na line 88 of aes_ige.c.

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

Twierdzenie zasadzie sprawdza, czy length (przekazywany do funkcji 3rd parametr) jest całkowitą wielokrotnością AES_BLOCK_SIZE. Jeśli tak, wykonywanie jest kontynuowane, w przeciwnym razie program zatrzymuje się i drukuje ostrzeżenie o niepowodzeniu zapewniania.

  1. więc upewnić się, że rozmiar danych są przekazywane do AES_ige_encrypt() jest wielokrotnością AES_BLOCK_SIZE.

  2. Jeśli wielkość danych nie jest całkowitą wielokrotnością, a następnie dołączyć NUL bajtów do niego, aby łączna wielkość najbliższą wielokrotnością AES_BLOCK_SIZE.

  3. Ponadto, zawsze przechodzą "integralną-stwardnienie-of AES_BLOCK_SIZE" wartość jako parametr do AES_ige_encrypt()length.

+0

Dzięki za wyjaśnienie. Wiem, skąd pochodzi błąd, ale nie mogę zrozumieć, dlaczego. W moim [poprzednim kodzie] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc256-encryption-decryption-with-openssl-c) I nie zrobiłem żadnej wyściółki i zadziałało. Przekazałem do 'AES_cbc_encrypt' dane wejściowe o długości podanej przez użytkownika (bez dopełnienia!), Więc dlaczego teraz nie działa? Zrobiłem inny przykładowy kod: http://pastie.org/private/yzlkcudvpwwfczvpvo8gw i wydaje się, że teraz jest OK. Jakieś pomysły, dlaczego nie mogę zrobić tak samo jak wcześniej? – ivy

+0

Kolejne pytanie;) Więc dla każdego szyfru blokowego muszę przekazać dane wejściowe będące wielokrotnością CIPHERs_BLOCK_SIZE? Czy to prawda dla KAŻDEGO szyfru o rozmiarze bloku? Dzięki :) – ivy

+4

Wcześniej, gdy zadzwoniłeś [** 'AES_cbc_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/aes__cbc_8c_source.html#l00055), nazwa wewnętrznie nazywała się [** 'CRYPTO_cbc128_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/cbc128_8c.html#a5cbe79f5b3a935a6e49ac72e3f3e4fb2), który nie ma ograniczeń co do długości danych użytkowych, które mają zostać zaszyfrowane. Dlatego nie dostałeś żadnego błędu. – TheCodeArtist

Powiązane problemy