2013-08-11 10 views
5

Son zamanlarda (stackoverflow kullanıcısı, @WhozCraig yardımıyla) CBC modunda AES çalışmaya başladı. Şimdi, aynı şeyi AES IGE ile yapmak istiyorum. openssl-1.0.1e/test/igetest.c'a bir göz attım ve kendi testimi oluşturmaya çalıştım. Ama bir kez daha, girişler ve çıktılar uygun boyutlarda bir sorunum var. Diğer her şey iyidir, çünkü önceki kodumdan kopyaladım: AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C. Ben az 32 olan bir giriş uzunluğu geçerkenAES (aes-ige-128, aes-ige-192, aes-ige-256) openssl ile şifreleme/şifre çözme C

Şimdi, diyor :

:

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) 

Ama boy eğer onun bütün Tamam, Im çok emin değilim ayrıca 32 daha büyük olduğu zaman

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 

İşte kod: SON

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

!

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

:; bu kod aşağıda% 100 iyi olduğunu, (öyledir) .Ama birisi diyebiliriz eğer Veeery minnettar olacaktır çalışma var)

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

Sadece bu değişti içine

:

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

doğruysa?

DÜZENLEME No.2; senin öneriler girişine bazı dolgu ilave ile)

Tamam adamlar, başka bir örnek yaptık. Umarım şimdi iyi olur mu?

#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: Bir süreliğine biraz daha rahatsız edebilir miyim? Lütfen buraya yapıştırdığım ikinci koduma bakıp sadece doğru olup olmadığını söyler misiniz? 'AES_ige_encrypt' ile olan asıl sorun -' encslength 'yerine' inputslength 'yazdığımda garip bir hata aldım: aes_ige.c (88): OpenSSL iç hatası, onaylama başarısız oldu: (uzunluk% AES_BLOCK_SIZE) == 0 ' – ivy

+2

Eğer herhangi bir dolgu yapmıyorsanız (sıfır baytlı dolgu veya başka bir şekilde), düz metninize blok boyutunun tam olarak N olması gerekir. Bunun hangi kısmı size açık değil? IGE, bu konuda CBC ile aynıdır. –

+0

@owlstead: Cevabınız için teşekkürler. Evet, dün bunun hakkında çok şey okudum ve şimdi bana açık olduğunu düşünüyorum. Ama gerçekten anlayamadığım bir şey daha var. [Önceki kodumda] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c) I herhangi bir dolgu yapmadı ve her şey iyiydi. Demek istediğim, AES_cbc_encrypt'a kullanıcı tarafından verilen uzunluğa (dolgu olmadan!) Girdim, neden şimdi çalışmıyor? – ivy

cevap

4

hata mesajı her şeyi söylüyor.

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

Bu temelde nedeniyle line 88 of aes_ige.c de kaynak fonksiyonu AES_ige_encrypt(), bu sağlanan geçersiz giriş için başarısız bir çalışma zamanı kontrol eder (onaylama) 'dir. length (işleve geçirilen 3 parametresi) AES_BLOCK_SIZE arasında bir tam katı olduğunda

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

onaylama temelde kontrol eder. Varsa, yürütme devam eder, aksi halde program durur ve başarısız olan iddia hakkındaki uyarıyı yazdırır.

  1. Yani veri boyutu AES_ige_encrypt() geçirilen sağlamak AES_BLOCK_SIZE bir katıdır.veri boyutu birden ayrılmaz değilse

  2. ardından toplam boyutu AES_BLOCK_SIZE yakın çoklu hale getirmek için ona NUL bayt ekleyin.

  3. Ayrıca, her zaman AES_ige_encrypt() için length parametre olarak "yekpare-çoklu-of AES_BLOCK_SIZE" değeri geçirir.

+0

Açıklama için teşekkürler. Hatanın nereden geldiğini biliyorum ama nedenini anlayamıyorum. [Önceki kodumda] (http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c) I herhangi bir dolgu yapmadı ve işe yaradı. AES_cbc_encrypt'e kullanıcı tarafından verilen (bir dolgu olmadan!) Uzunluğa sahip bir girdiye geçtim, neden şimdi çalışmıyor? Başka bir örnek kod yaptım: http://pastie.org/private/yzlkcudvpwwfczvpvo8gw ve şimdi iyi görünüyor. Daha önce neden aynı şeyi yapamadığım hakkında bir fikrin var mı? – ivy

+0

Başka bir soru;) Yani her blok boyutlu şifre için bir CIPHERs_BLOCK_SIZE katsayısı olan bir girişi geçmek zorundayım? HER blok blok şifresi için bu doğru mu? Teşekkürler :) – ivy

+4

Daha önce, [** 'AES_cbc_encrypt()' **] 'i çağırdığınızda (http://fossies.org/dox/openssl-1.0.1e/aes__cbc_8c_source.html#l00055), dahili olarak [** Şifrelenecek veri yükünün uzunluğu üzerinde herhangi bir kısıtlama bulunmayan CRYPTO_cbc128_encrypt() '**] (http://fossies.org/dox/openssl-1.0.1e/cbc128_8c.html#a5cbe79f5b3a935a6e49ac72e3f3e3f4e4fb2). Bu nedenle herhangi bir hata almadı. – TheCodeArtist