2014-01-15 2 views
0

Blowfish의 CBC 블록 모드를 사용하여 문자열을 암호화하고 해독하려고 OpenSSL 라이브러리를 사용하려고합니다. 플랫폼상의 이유로 이것은 C++보다는 스트레이트 -C에서 수행되어야합니다. 입력 문자열이 8 자 (1 블록)보다 길면 어떤 이유로 출력 크기가 크게 늘어납니다.Blowfish CBC 모드 및 버퍼 오버런

예 : abcdefgh를 암호화하면 길이가 8 자로 출력됩니다. 모두 양호합니다. 그러나 abcdefgha를 암호화하면 699 자의 출력이 생성됩니다!

나는이 라이브러리에 근본적으로 잘못된 것을하고 있습니까? Blowfish의 출력이 입력과 동일한 크기 여야한다는 것이 내 이해입니다. 아무도 내가 이것을 잘못하고 있다고 설명 할 수 있습니까? 이것이 맞으면 입력이 1 블록을 초과 할 때이 코드가 오버런하여 출력 버퍼를 얼마나 크게 생성하는지 알 수 있습니까? 아래

코드 샘플 : 사용자의 입력 문자열을 암호화하는 경우

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <openssl/blowfish.h> 
const unsigned char* BLOWFISH_KEY = "TestKey!"; 
#define SIZE 8 

unsigned char* blowfish_decrypt(unsigned char* in); 
unsigned char* blowfish_encrypt(unsigned char* in); 

int main(){ 

    char* message = "abcdefgha"; 

    char* encrypted = blowfish_encrypt(message); 
    printf("Encrypted: %s\n", encrypted); 
    printf("Size of encrypted: %d\n\n", strlen(encrypted)); 

    char* decrypted = blowfish_decrypt(encrypted); 
    printf("Decrypt: %s\n", decrypted); 
    printf("Size of encrypted: %d\n\n", strlen(encrypted)); 
    return 0; 

} 

unsigned char* blowfish_encrypt(unsigned char* in){ 

    int i; 
    int SIZE_IN = strlen(in); 
    unsigned char *out = calloc(SIZE_IN+1, sizeof(char)); 

    char ivec[8]; 
    for(i=0; i<8; i++) ivec[i] = 'i'; 

    BF_KEY *key = calloc(1, sizeof(BF_KEY)); 

    /* set up a test key */ 
    BF_set_key(key, SIZE, BLOWFISH_KEY); 

    BF_cbc_encrypt(in, out, strlen(in), key, ivec, BF_ENCRYPT); 

    printf("Size of out: %d\n", strlen(out)); 
    printf("Size of in: %d\n", strlen(in)); 
    return out; 
} 

unsigned char* blowfish_decrypt(unsigned char* in){ 

    int i; 
    int SIZE_IN = strlen(in); 
    unsigned char *out = calloc(SIZE_IN+1, sizeof(char)); 

    char ivec[8]; 
    for(i=0; i<8; i++) ivec[i] = 'i'; 

    BF_KEY *key = calloc(1, sizeof(BF_KEY)); 

    /* set up a test key */ 
    BF_set_key(key, SIZE, BLOWFISH_KEY); 

    BF_cbc_encrypt(in, out, strlen(in), key, ivec, BF_DECRYPT); 

    printf("Size of out: %d\n", strlen(out)); 
    printf("Size of in: %d\n", strlen(in)); 
    return out; 
} 

답변

3

는, 결과 데이터가 더 이상 당신은 그것의 길이를 얻을 수 strlen()를 사용할 수있는 문자열입니다. 데이터를 이진 스트림으로 만 처리 할 수 ​​있습니다.

Blowfish는 블록 암호이므로 입력 길이가 블록 크기의 배수인지 확인하고 입력 길이가 맞지 않으면 채우기를 처리해야합니다. 출력 길이는 간단한 테스트를 위해 적절한 패딩을 수행 할 때 입력 한 것과 동일합니다.

더 높은 수준의 EVP 암호화/암호 해독 기능 http://linux.die.net/man/3/evp_encryptinit을 사용할 수 있습니다. 패딩은 기본적으로 활성화되어 있습니다.

+0

감사합니다. 저를 붙잡은 것은 블록 크기였습니다. strlen을 디버깅을 위해 붙였습니다. 이전에 Base64를 사용하여 결과를 인코딩하고 결과적으로 다소 큰 문자열을 얻었습니다. – user1763100