2012-04-14 63 views
1

含空字符(\ X00),我有以下字符串加密字符串:无法解密使用OpenSSL的

char *str = "\x45\x00\x10"; 

我需要使用的OpenSSL加密它,把它通过网络和解密找回同一字符串。

我用于加密以下代码(编程下在Ubuntu Linux操作系统):

int do_encrypt(char *cipher, char *key, char *iv, char *plaintext, int len) 
{ 
    unsigned char outbuf[BUFSIZE]; 
    int outlen, tmplen; 
    EVP_CIPHER_CTX ctx; 
    EVP_CIPHER_CTX_init(&ctx); 
    EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); 

    if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, plaintext, len)) 
    { 
      EVP_CIPHER_CTX_cleanup(&ctx); 
      return 0; 
    } 

    if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen)) 
    { 
      EVP_CIPHER_CTX_cleanup(&ctx); 
      return 0; 
    } 

    outlen += tmplen; 
    EVP_CIPHER_CTX_cleanup(&ctx); 

    outbuf[outlen] = '\0'; 
    strcpy(cipher,outbuf); 
    return 1; 
} 

我使用下面的代码进行解密:

int do_decrypt(char *plain, char *key, char *iv, char *cipher) 
{ 
    unsigned char outbuf[BUFSIZE]; 
    int outlen, tmplen; 
    EVP_CIPHER_CTX ctx; 

    EVP_CIPHER_CTX_init(&ctx); 
    EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); 

    if(!EVP_DecryptUpdate(&ctx, outbuf, &outlen, cipher, strlen(cipher))) 
    { 
      EVP_CIPHER_CTX_cleanup(&ctx); 
      return 0; 
    } 

    if(!EVP_DecryptFinal_ex(&ctx, outbuf + outlen, &tmplen)) 
    { 
      EVP_CIPHER_CTX_cleanup(&ctx); 
      return 0; 
    } 

    outlen += tmplen; 
    EVP_CIPHER_CTX_cleanup(&ctx); 

    outbuf[outlen] = '\0'; 
    strcpy(plain,outbuf); 

    return outlen; 
} 

当我str加密使用所述第一函数,并通过第三个参数为3(我不希望传递的strlen(STR),因为它不会加密整个字符串),并使用第二功能解密,我得到下面的纯文本回:

\x45\x00\x00 // recovered plain text 

我应该对我的代码做些什么修正,以便我可以加密整个字符串并仍然得到整个字符串,即使原始字符串包含空字符?

谢谢。

+3

不要使用设计用于空终止字符串(如'strcpy'和'strlen')存储在无符号'char'阵列的二进制数据的功能。你需要明确地跟踪长度;密文包含从0到255的所有值。 – erickson 2012-04-14 05:05:21

回答

4

你... 知道strcpy()会停在第一个NUL,对吗?改为使用strncpy()

+2

'strncpy'?为什么不只是'memcpy'? – 2012-04-14 06:45:11

+0

需要更少的编辑。 *运行* – 2012-04-14 06:47:28

+2

strncpy()= will =在遇到的第一个NUL字节处停止。正确的方法是mem *()系列。 – 2012-05-12 18:36:01