2012-05-18 2 views
0

아래 코드가 있습니다. 내 문제는 내가 암호화 된 및 해독 된 문자 배열의 이상한 결말을 가지고.OpenSSL AES 잘못된 암호화

클리어 텍스트 : aaaaaaaaabbbbbbbbbbbbbbccccccccc 암호화 되 텍스트 : ЁТ☼ 번호의 єз▬├ ^^ °, ♦ Ёфм : ЇъШ╙y╒КzukЩu @ 8¤ 내가 콘솔에 점점이 코드

#include <iostream> 
#include <openssl\evp.h> 

#define AES_BLOCK_SIZE 16 

static EVP_CIPHER_CTX Encrypt_Context, Decrypt_Context; 

int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx, 
      EVP_CIPHER_CTX *d_ctx) 
{ 
    int i, nrounds = 1; 
    unsigned char key[16], iv[16]; 

    i = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv); 
    if (i != 16) { 
    printf("Key size is %d bits - should be 128 bits\n", i); 
    return -1; 
    } 

    EVP_CIPHER_CTX_init(e_ctx); 
    EVP_EncryptInit_ex(e_ctx, EVP_aes_128_cbc(), NULL, key, iv); 
    EVP_CIPHER_CTX_init(d_ctx); 
    EVP_DecryptInit_ex(d_ctx, EVP_aes_128_cbc(), NULL, key, iv); 

    return 0; 
} 

unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len) 
{ 
    int c_len = *len + AES_BLOCK_SIZE, f_len = 0; 
    unsigned char *ciphertext = (unsigned char *)malloc(c_len); 
    EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL); 
    EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len); 
    EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len); 
    *len = c_len + f_len; 
    return ciphertext; 
} 

unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len) 
{ 
    int p_len = *len, f_len = 0; 
    unsigned char *plaintext = (unsigned char*)malloc(p_len); 
    EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL); 
    EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len); 
    EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len); 
    *len = p_len + f_len; 
    return plaintext; 
} 

void main() 
{ 
    unsigned char * data_to_encrypt = (unsigned char*)"aaaaaaaaabbbbbbbbbbbbbbccccccccc"; 
    unsigned char *key_data = (unsigned char *)"aaaaaaaaaaaaaaaa"; 
    int key_data_len = strlen((const char*) key_data); 
    char * ciphertext; 
    char * plaintext; 

    aes_init(key_data, 16, NULL, &Encrypt_Context, &Decrypt_Context); 

    int length = strlen((const char*) data_to_encrypt)-1; 

    printf("Clear text :%s\n", data_to_encrypt); 

    ciphertext = (char *)aes_encrypt(&Encrypt_Context, data_to_encrypt, &length); 
    printf("Crypted text :%s\n", ciphertext); 

    plaintext = (char *)aes_decrypt(&Decrypt_Context, (unsigned char*)ciphertext, &length); 
    printf("Decrypted text :%s\n", plaintext); 
} 

═══════════════¤¤¤¤ 해독 된 텍스트 : aaaaaaaaabbbbbbbbbbbbbbcccccccc☺¤¤¤¤ 무엇이며

═════════════ à == ¤¤¤¤ ¤ 암호화 된 텍스트의 끝에서 ¤¤¤¤ 결국의 해독? 내 코드에 무슨 문제가 있습니까?

감사합니다.

+0

내 코드가 잘 작동하므로 패딩이 가능합니다. :) – 0xC0000022L

답변

2

암호화 루틴은 C 문자열이 아니라 이진 데이터를 처리하므로 포인터를 반환하는 배열은 null로 끝나지 않으므로 printf (null로 끝나는 문자열이 필요함)으로 인쇄 할 때 임의로 표시됩니다 이 어레이 바로 다음에 위치하는 쓰레기.

해결하려면 null-termination을 확인하고 fwrite과 같은 문자를 사용하거나 문자를 반복하여 배열을 인쇄하십시오.

+0

? 그냥 printf 문제일까요? – Roman

+0

@Roman : 그렇습니다. – Fanael

2

ciphertextplaintext은 C 스타일 문자열이 아닙니다. 이것들은 단지 unsigned char 배열에 대한 포인터 일뿐입니다. printf%s 지정자는 인쇄하기 위해 Null 종료 문자열을 요구합니다.

  • 것은 (당신이 자신의 길이를 알고 있기 때문에) 모두 ciphertextplaintext이 null로 끝나는 배열을 통해
  • 루프 있는지 확인하고 모든, 일반적으로 각 문자를 개별적으로

인쇄 : 당신은 두 가지 선택이 암호화에서 그러한 바이트 - 스트링은 16 진법을 사용하기 때문에, 후자의 경우 더 나을 것이다.

0

대부분의 암호화 알고리즘은 암호화 된 메시지의 정확한 길이에서 정보를 추론 할 수 없도록 암호화 전에 데이터를 채 웁니다. 일부 도구는 데이터를 암호화하기 전에 압축을 추가 (패딩 이후)합니다.

따라서 긴 문자 열이 패딩 될 가능성이 큽니다.

나머지는 초기화되지 않은 데이터가 있음을 의미합니다. 즉, 버퍼가 실제 메시지 뒤에 0으로 채워지지 않으므로 길을 따라 가비지를 암호화 할 수 있습니다. 또는 해독 할 때 해독 된 데이터가 중지되는 지점에서 문자열로 예상되는 내용을 제로 - 종료하지 않습니다.