1

次の文字列があります。

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

openssl を使用して暗号化し、ネットワーク経由で送信し、復号化して同じ文字列を取得する必要があります。

暗号化には次のコードを使用します (Ubuntu Linux での C でのプログラミング)。

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 番目の引数を 3 として渡し (文字列全体を暗号化しないため、strlen(str) を渡したくありません)、2 番目の関数を使用して復号化すると、次のプレーンが得られます。テキストバック:

 \x45\x00\x00 // recovered plain text

元の文字列に null 文字が含まれていても、文字列全体を暗号化して文字列全体を取得できるようにするには、コードをどのように修正すればよいですか?

ありがとう。

4

1 に答える 1

4

あなたは...それstrcpy()が最初のNULで停止することを知っていますよね?strncpy()代わりに使用してください。

于 2012-04-14T04:24:11.150 に答える