0

私の考えは、クライアントサーバーモデルでファイル暗号化を行うことであり、暗号化の目的でopenssl evpを使用しています。暗号文をテキスト ファイルに保存し、クライアントに送信する必要があります。しかし、ファイルに保存できない暗号文に無効な文字が存在するため、これを行うことができません。

これは暗号化のための私のコードです:

EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_256_ctr(), NULL, NULL, NULL,
        do_encrypt);
OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == 32);
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == 16);

EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);

//receive the file contents in chunks of 1024 bytes
while ((inlen = recv(connfd, inbuf, sizeof inbuf, 0)) > 0) {
    fprintf(stdout,"\nReceived %d bytes",inlen);
    fflush(stdout);
    fprintf(stdout,"\nOriginal: %s",inbuf);
    fflush(stdout);
    //use encrypt_update() to encrypt the chunks
    if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 0;
    }
    //write the encrypted text to out file
    fprintf(stdout,"\nEncrypted: %s %d",outbuf, inlen);
    fflush(stdout);
    fwrite(outbuf, sizeof(char), outlen, fp);
    //clear the buffer
    memset(inbuf,0, strlen(inbuf));
    memset(outbuf,0, strlen(outbuf));
}
//use encrypt_final() to encrypt the final letf out block of chunk is any
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) {
    /* Error */
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 0;
}
//write the encrypted text to out file
fwrite(outbuf, sizeof(char), outlen, fp);
EVP_CIPHER_CTX_cleanup(&ctx); //cleanup
fclose(fp); //close the file

このリンクを参照して、復号化を伴う無効な文字の問題が報告され、解決されました。

openssl evp api (aes256cbc) を使用したファイルの暗号化に関する問題

誰かがここで私を助けてくれることを願っています。

前もって感謝します。

4

1 に答える 1

1

openssl evp aes_256_ctr() モードでの暗号化中に生成された無効な文字...

...ファイルに保存できない無効な文字が暗号文に存在することがわかったため

これはあなたの問題だと思います。それは完全に正しくありません。

ファイルには何でも (任意の文字) を格納できます。C 文字列は少し異なりますが、文字列を扱っているわけではありません。

すべての文字は、暗号文に含まれる可能性が等しく、0x00、0x01、... 'A'、'B'、... 'a'、'b'、...、0xFE、 0xFF)。


fprintf(stdout,"\nオリジナル: %s",inbuf);

inbufが埋め込まれている場合、これは問題になる可能性がありますNULL。文字列ではなくファイルを扱っていると思いましたか?


memset(inbuf,0, strlen(inbuf));
memset(outbuf,0, strlen(outbuf));

イリジウムが言ったように、これらは必要ありません。次のような関数の戻り値を使用する必要がありますrecv(また、暗号文に含まれる可能性が同等であるため、識別文字に依存しないでくださいNULL(0x00、0x01、... 'A'、'B'、 ... 'a'、'b'、...、0xFE、0xFF)。


EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_256_ctr(), NULL, NULL, NULL, do_encrypt);
...

戻り値も無視します。それは通常悪い考えです。

于 2014-12-21T13:04:45.800 に答える