2013-08-11 26 views
5

Recentemente, infine, con l'aiuto dell'utente di stackoverflow, @WhozCraig, ho ottenuto il funzionamento AES in modalità CBC. Ora, vorrei fare esattamente la stessa cosa ma con AES IGE. Ho dato un'occhiata a openssl-1.0.1e/test/igetest.c e ho provato a costruire il mio test. Ma ancora una volta, ho un problema con ingressi e uscite di dimensioni adeguate. Tutto il resto è buono, perché l'ho copiato dal mio codice precedente: 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) crittografia/decodifica con openssl C

Ora, quando passo una lunghezza ingressi che è inferiore a 32, si dice:

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) 

Ma quando la lunghezza è maggiore di 32, Im anche non così sicuro se tutto 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 il codice:

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

FINALMENTE! Ottenuto che funziona (spero) .Ma sarei mooolto grato se qualcuno può dire, che questo codice qui sotto è al 100% buono;)

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

ho cambiato solo questo:

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

in quel:

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

è corretto?

EDIT No.2;)

Ok ragazzi, ha fatto un altro esempio, con i vostri consigli aggiunto qualche imbottitura per l'ingresso. Spero che sia ok adesso?

#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: posso disturbarti un po 'di più per un po'? Potresti per favore guardare il mio secondo codice che ho incollato qui e dire solo se è corretto o no? Il problema principale che ho con 'AES_ige_encrypt' - quando passo' inputslength' invece di 'encslength' ho uno strano errore:' aes_ige.c (88): errore interno OpenSSL, asserzione fallita: (lunghezza% AES_BLOCK_SIZE) == 0 ' – ivy

+2

Se non si esegue alcun padding (padding zero byte o altro), allora è necessario che il testo normale sia esattamente N volte la dimensione del blocco. Quale parte di questo non ti è chiara? IGE è lo stesso di CBC in questa materia. –

+0

@owlstead: Grazie per la risposta. Sì, ne ho letto molto ieri e ora mi sembra chiaro. Ma c'è solo un'altra cosa che non riesco a capire. Nel mio [codice precedente] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c) I non ha fatto alcuna imbottitura, ed è andato tutto bene. Voglio dire, ho passato a 'AES_cbc_encrypt' un input con la lunghezza data dall'utente (senza un padding!), Quindi perché ora non funziona? – ivy

risposta

4

Il messaggio di errore dice tutto.

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

Questo è fondamentalmente un run-time-controllo (asserzione) che fallisce a causa di input non valido fornito alla funzione AES_ige_encrypt() presenti nella fonte al line 88 of aes_ige.c.

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

L'asserzione fondamentalmente controlla se length (3 ° parametro passato alla funzione) è un multiplo intero di AES_BLOCK_SIZE. In caso affermativo, l'esecuzione continua, altrimenti il ​​programma si ferma e viene stampato un avvertimento relativo all'asserita violazione.

  1. Quindi assicurarsi che la dimensione dei dati che vengono passati al AES_ige_encrypt() è un multiplo di AES_BLOCK_SIZE.

  2. Se la dimensione dei dati non è un multiplo intero, quindi aggiungere NUL byte ad esso per rendere la dimensione totale multipli di AES_BLOCK_SIZE.

  3. Inoltre, sempre il passaggio "integrale multiplo-di- AES_BLOCK_SIZE" valore del parametro length a AES_ige_encrypt().

+0

Grazie per la spiegazione. So da dove viene l'errore, ma non capisco perché. Nel mio [codice precedente] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c) I non ha fatto alcuna imbottitura, e ha funzionato. Ho passato a 'AES_cbc_encrypt' un input con la lunghezza data dall'utente (senza padding!), Quindi perché ora non funziona? Ho fatto un altro codice di esempio: http://pastie.org/private/yzlkcudvpwwfczvpvo8gw e sembra che sia ok ora. Qualche idea per cui non posso fare lo stesso come prima? – ivy

+0

Un'altra domanda;) Quindi per ogni cifrario a dimensione di blocco devo passare un input che è un multiplo di CIPHERs_BLOCK_SIZE? È vero per OGNI cifra cifrata? Grazie :) – ivy

+4

In precedenza, quando hai chiamato [** 'AES_cbc_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/aes__cbc_8c_source.html#l00055), ha chiamato internamente [** 'CRYPTO_cbc128_encrypt()' **] (http://fossies.org/dox/openssl-1.0.1e/cbc128_8c.html#a5cbe79f5b3a935a6e49ac72e3f3e4fb2) che non ha alcuna restrizione sulla lunghezza dei dati del carico utile da crittografare. Quindi non hai ricevuto alcun errore. – TheCodeArtist

Problemi correlati