次の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);
}
誰でも解決策を提案したり、問題を指摘したりできますか?
ありがとう。