3

次の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

復号化関数に 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);
}

誰でも解決策を提案したり、問題を指摘したりできますか?

ありがとう。

4

0 に答える 0