OpenSSL:EVP_DecryptFinal_ex中发生错误

时间:2012-04-25 20:25:38

标签: c linux openssl encryption

我有以下openssl解密代码:

int decrypt(unsigned char *plain, unsigned char *key, unsigned char *iv, unsigned char *cipher, int len)
{
    int i;

    unsigned char outbuf[2000];
    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, len))
    {
            EVP_CIPHER_CTX_cleanup(&ctx);
            return 0;
    }

    printf("\nBytes decrypted (outlen) : %d\n",outlen);

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

    printf("\nBytes decrypted (tmplen) : %d\n",tmplen);

    outlen += tmplen;
    EVP_CIPHER_CTX_cleanup(&ctx);

    printf("\nLength decrypted :%d\n",outlen);

    printf("\nOutbuf: ");
    for(i=0; i<outlen; i++){
       plain[i] = outbuf[i];    
       printf(" %02x ",outbuf[i]);
    }
    printf("\n");
        return outlen;
}

ctx初始化如下:

SSL_library_init();
SSL_load_error_strings();
meth = SSLv23_server_method();
ctx = SSL_CTX_new (meth);
if (!ctx) {
     ERR_print_errors_fp(stderr);
     exit(1);
}
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); 
SSL_CTX_load_verify_locations(ctx,CACERT,NULL);

if (SSL_CTX_use_certificate_file(ctx, "./server.pem", SSL_FILETYPE_PEM) <= 0) {
       ERR_print_errors_fp(stderr);
       exit(1);
}
if (SSL_CTX_use_PrivateKey_file(ctx, "./server.key", SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(1);
}

使用以下命令生成server.key文件:

openssl genrsa -des3 -out server.key 1024

我将decrypt函数传递给unsigned char *类型的密码,密码长度为16个字节(纯文本为2个字节),密钥长度为16个字节(unsigned char),IV为长度为8个字节(unsigned char)

我从解密函数中获得以下输出:

 Bytes decrypted (outlen) : 0
 19637:error:06065064:digital envelope routines: EVP_DecryptFinal_ex: bad decrypt: evp_enc.c: 337:

以下是evp_enc.c的来源:

 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i,n;
unsigned int b;

*outl=0;
b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING)
    {
    if(ctx->buf_len)
        {
        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
        return 0;
        }
    *outl = 0;
    return 1;
    }
if (b > 1)
    {
    if (ctx->buf_len || !ctx->final_used)
        {
        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
        return(0);
        }
    OPENSSL_assert(b <= sizeof ctx->final);
    n=ctx->final[b-1];
    if (n == 0 || n > (int)b)
        {
        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
        return(0);
        }
    for (i=0; i<n; i++)
        {
        if (ctx->final[--b] != n)
            {
             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT); // 337
            return(0);
            }
        }
    n=ctx->cipher->block_size-n;
    for (i=0; i<n; i++)
        out[i]=ctx->final[i];
    *outl=n;
    }
else
    *outl=0;
return(1);
}

有人可以建议解决方案/指出问题吗?

感谢。

0 个答案:

没有答案