2013-08-09 15 views
18

Sadece bu 3 mod ile openSSL'den AES'yi test etmek istiyorum: 128,192 ve 256 anahtar uzunluğu ile Şifresi çözülmüş metin girdimden farklı ve nedenini bilmiyorum. Ayrıca, büyük bir giriş uzunluğunu geçtiğimde (1024 bayt diyelim) programım core dumped gösterir ... Benim girişim her zaman aynıdır, ama en azından şimdilik önemli değil. İşte kod:AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) openssl ile şifreleme/şifre çözme C

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <openssl/aes.h> 

int main(int argc, char **argv) 
{ 
    int i; 
    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]; 
    memset(aes_key, 0, sizeof(aes_key)); 
    if (!RAND_bytes(aes_key, keylength)) 
    { 
     exit(-1); 
    } 
    aes_key[keylength-1] = '\0'; 

    int inputslength; 
    printf("Give an input's length:\n"); 
    scanf("%d", &inputslength); 

    /* generate input with a given length */ 
    unsigned char aes_input[inputslength+1]; 
    memset(aes_input, '0', sizeof(aes_input)); 
    aes_input[inputslength] = '\0'; 

    /*printf("original:\t"); 
    for(i=0; i<inputslength; i++) 
    { 
     printf("%c ", aes_input[i]); 
    } 
    printf("\n");*/ 

    /* init vector */ 
    unsigned char iv[AES_BLOCK_SIZE]; 
    if (!RAND_bytes(iv, AES_BLOCK_SIZE)) 
    { 
     exit(-1); 
    } 

    //printf("AES_BLOCK_SIZE = %d\n", AES_BLOCK_SIZE); // aes block size is 16 bytes = 128 bits 
    AES_KEY enc_key, dec_key; 
    unsigned char enc_out[AES_BLOCK_SIZE]; 
    unsigned char dec_out[AES_BLOCK_SIZE]; 

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256 
    AES_set_encrypt_key(aes_key, keylength, &enc_key); 
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT); 

    AES_set_decrypt_key(aes_key, keylength, &dec_key); 
    AES_decrypt(enc_out, dec_out, &dec_key); 

    printf("original:\t"); 
    for(i=0;*(aes_input+i)!=0x00;i++) 
     printf("%X ",*(aes_input+i)); 
    printf("\nencrypted:\t"); 

    for(i=0;*(enc_out+i)!=0x00;i++) 
     printf("%X ",*(enc_out+i)); 

    printf("\ndecrypted:\t"); 
    for(i=0;*(dec_out+i)!=0x00;i++) 
     printf("%X ",*(dec_out+i)); 
    printf("\n"); 

    /*printf("\n\noriginal:\t"); 
    for(i=0; i<inputslength; i++) 
    { 
     printf("%x ", dec_out[i]); 
    } 
    printf("\n");*/ 


    return 0; 
} 

DÜZENLEME: Ben sonuçlar elde ettim yerine AES_BLOCK_SIZE ait inputslength için çıkışları boyutları değişti

:

Give a key length [only 128 or 192 or 256!]: 
128 
Give an input's length: 
5 
original:  30 30 30 30 30 
encrypted:  94 56 50 7E 19 B2 1C CE 20 23 4A E7 10 AF DB E3 30 30 30 30 30 
decrypted:  E1 5F F4 3D E8 8D 91 19 CD 3E 22 1E AF 1C 8F 5A 94 56 50 7E 19 B2 1C CE 20 23 4A E7 10 AF DB E3 30 30 30 30 30 

yüzden mümkün olduğunu outpus ile gidecekseniz bir sorun boyutları ve iv boyutu? Ne boyutları olmalıdır (AES-CBC-128, AES-CBC-192, AES-CBC-256 için)?

+2

Sidenote: AES anahtarınızın boş bırakılmasına gerek yoktur. onun rasgele bir bayt bloğu; bu kadar. Bu konuda null-term hiç bir şey yok, yani aes_key [keylength-1] = '\ 0' 'anlamsızdır (her zaman anahtarınızın son baytını (olması gerekenden 8x daha büyük olan) sıfır olarak ayarlar. – WhozCraig

+0

@WhozCraig: teşekkürler, bunu bilmek güzel. Asıl sorun ne dersin, herhangi bir fikrin var mı? – ivy

+1

Plenty. Şifreleme ve şifre çözme için tampon boyutları hiçbir yerde * yeterince * yeterince büyük. ve bu şeyleri karakter verileri olarak ele almaya çalışmak yerine, genel bir hex yazdırma işlevine ihtiyacınız var. * Bu ikili *. Şimdi resmi bir cevap oluşturmak, ama oraya bakmaya başlamak. – WhozCraig

cevap

25

Kodunuzun bu değiştirilmiş sürümünde bir göz atın.

  1. Eklenen hex_print (küçük) anahtar tamponu (ortam) ve
  2. eklendi uygun şekilde boyutlandırılması: Aşağıdaki edin.
  3. Çıkış şifreleme arabelleğinin düzgün boyutlandırılması eklendi (bu, bir blok boyutu birden çok olmalı ve orijinal kaynak arabelleği tam bir blok boyutu çoklu ise, hala bir dolgu bloğuna ihtiyacınız var (daha fazla bilgi için bkz. PKCS 5 dolgu) .
  4. aynı IV, her iki şifreleme için kullanılan ve şifresini çözer.
  5. son olarak, tek bu AES_cbc_encrypt() (çağrı son parametre bakınız) şifreleme ve şifre çözme için kullanılan görünse de.

Kaynak Kodu

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

    /* init vector */ 
    unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE]; 
    RAND_bytes(iv_enc, AES_BLOCK_SIZE); 
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE); 

    // 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_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT); 

    AES_set_decrypt_key(aes_key, keylength, &dec_key); 
    AES_cbc_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; 
} 

Test Çıkışı

Give a key length [only 128 or 192 or 256!]: 
128 
Give an input's length: 
10 
original: 58 58 58 58 58 58 58 58 58 58 
encrypt: A9 66 C5 24 A4 02 AB 96 08 65 F7 22 A5 FB BE 26 
decrypt: 58 58 58 58 58 58 58 58 58 58 

İkinci Testi Çıktı

Give a key length [only 128 or 192 or 256!]: 
128 
Give an input's length: 
10 
original: 58 58 58 58 58 58 58 58 58 58 
encrypt: C2 47 6D B1 A1 68 29 53 55 74 C5 CC 3F 27 0A 3F 
decrypt: 58 58 58 58 58 58 58 58 58 58 

Umarım bu yardımcı olur umarım.

+0

Rahatsız ettiğim için özür dilerim, haklısın, artık her şey yolunda :) – ivy

3

@WhozCraig: Yardımlarınız için çok teşekkür ederim! Bana çok şey anlattı! Ama sadece bir sorun daha var. Statik dizileri dinamik olanlara değiştirdim. Yaptığımda, bazı hatalar oluştu. Ama onlar sadece büyük bir girdi boyutu verdiğimde ortaya çıkıyorlar, valgind çıkışına bir göz atıyorlar: http://pastie.org/private/bzofrrtgrlzr0doyb3g. Büyük bir girişten geçtiğimde, küçük bir boyuta geçtiğimde (örneğin örneğinizde, 10) hata oluşur. Her şey mükemmel çalışıyor.

#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) 
{ 
    size_t inputslength = 0; 
    printf("Give an input's length:\n"); 
    scanf("%lu", &inputslength); 

    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 = (unsigned char*)malloc(sizeof(unsigned char) * (keylength/8)); 
    memset(aes_key, 0, keylength/8); 
    RAND_bytes(aes_key, keylength/8); 

    // generate input with a given length 
    unsigned char *aes_input = (unsigned char*)malloc(sizeof(unsigned char) * (inputslength)); 
    memset(aes_input, 'X', sizeof(aes_input)); 

    // init vectors 
    unsigned char *iv_enc = (unsigned char*)malloc(sizeof(unsigned char) * (AES_BLOCK_SIZE)); 
    unsigned char *iv_dec = (unsigned char*)malloc(sizeof(unsigned char) * (AES_BLOCK_SIZE)); 
    // iv_dec == iv_enc 
    RAND_bytes(iv_enc, AES_BLOCK_SIZE); 
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE); 

    // buffers for encryption and decryption 
    const size_t length = (((inputslength + AES_BLOCK_SIZE)/AES_BLOCK_SIZE) * AES_BLOCK_SIZE); 
    unsigned char *enc_out = (unsigned char*)malloc(sizeof(unsigned char) * (length)); 
    unsigned char *dec_out = (unsigned char*)malloc(sizeof(unsigned char) * (inputslength)); 

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256 
    AES_KEY encKey, decKey; 
    AES_set_encrypt_key(aes_key, keylength, &encKey); 
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &encKey, iv_enc, AES_ENCRYPT); 

    AES_set_decrypt_key(aes_key, keylength, &decKey); 
    AES_cbc_encrypt(enc_out, dec_out, length, &decKey, 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)); 

    free(aes_key); 
    aes_key = NULL; 
    free(aes_input); 
    aes_input = NULL; 
    free(iv_enc); 
    iv_enc = NULL; 
    free(iv_dec); 
    iv_dec = NULL; 
    free(enc_out); 
    enc_out = NULL; 
    free(dec_out); 
    dec_out = NULL; 

    return 0; 
} 

DÜZENLEME:

Tamam, bir şeyler bile büyük girişler için, mükemmel çalışıyor, ben yayınlanmıştır önceki kod heres yenisi ile yanlıştı. Bana yardım ettiğin için bir kez daha şerefe!:)

#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 = (unsigned char*)malloc(sizeof(unsigned char) * (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 = (unsigned char*)malloc(sizeof(unsigned char) *inputslength); 
    memset(aes_input, 'X', inputslength); 

    /* init vector */ 
    unsigned char *iv_enc = (unsigned char*)malloc(sizeof(unsigned char) *AES_BLOCK_SIZE), *iv_dec = (unsigned char*)malloc(sizeof(unsigned char) *AES_BLOCK_SIZE); 
    RAND_bytes(iv_enc, AES_BLOCK_SIZE); 
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE); 

    // buffers for encryption and decryption 
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE)/AES_BLOCK_SIZE) * AES_BLOCK_SIZE; 
    unsigned char *enc_out = (unsigned char*)malloc(sizeof(unsigned char) *encslength); 
    unsigned char *dec_out = (unsigned char*)malloc(sizeof(unsigned char) *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_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT); 

    AES_set_decrypt_key(aes_key, keylength, &dec_key); 
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT); 

    printf("original:\t"); 
    hex_print(aes_input, inputslength); 

    printf("encrypt:\t"); 
    hex_print(enc_out, encslength); 

    printf("decrypt:\t"); 
    hex_print(dec_out, inputslength); 

    // free memory here 

    return 0; 
} 
+6

Yeniden bak. 'sizeof(), sabit veya değişken bir dizi yerine bir işaretçi ile kullanıldığında yepyeni bir anlam kazanır. Bir * işaretçisinin boyutu olur *, *** *** bunun için ayrılan verilerin boyutu değil. Tüm bedenleriniz değişken olmalı; ** değil ** 'sizeof (bir şey)'. Bunu düzelt ve bahse girerim son sorunların ortadan kalkacak. (sidenote: düzenli C dilinde programlama yaparken 'malloc()' komutunu kullanmayın. Bu özellikle taşınabilirlik için çok ince problemlere neden olabilir C++ bunu gerektirir, ancak daha sonra, C++ 'da 'malloc()' yi kullanmamalısınız. ilk etapta.) = P – WhozCraig

+1

tekrar çok teşekkürler sooo! İşte çalışma örneği: http://pastie.org/private/dtvmftozmru02webkzzq. Ben "malloc" beacuese bastım benim gcc benim için - malloc hatırladığım gibi geri döner söyledi? C++ 'da yazdığımda,' new 've' delete 'kullanıyorum, biliyorum C++' da malloc kullanmamalıyım;) – ivy

+2

C programlamadaki malloc() 'ın dökümünün kendi kendine ait potansiyel tuzakları var. Açıkçası C++ 'da gereklidir, fakat dediğiniz gibi,' new 've' delete 'komutlarını kullanırsınız. Bu sitede "döküm malloc [c]" araması yapılıyor. Onun oldukça tartışmalı bir konu. Bunun yanı sıra, koşup gittiğinize çok sevindim. – WhozCraig