Openssl EVP“EVP_CTRL_GCM_GET_TAG”실패

Sep 02 2020

C ++에서 Openssl EVP를 사용하고 있습니다. 어떻게 든 태그를 얻는 데 실패합니다. 내 코드 :

int do_crypt(FILE *in, FILE *out){
    unsigned char inbuf[1024], aadbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
    int inlen, lenbuf, unused, outlen;
    EVP_CIPHER_CTX *ctx;

    unsigned char key[] = "0123456789abcdeF";
    unsigned char iv[] = "123456788765";
    unsigned char tag[16];

    ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);
    EVP_CipherInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL, do_encrypt);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL);

    OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);
    OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 12);
    EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1);
    
    FILE * aad_f = fopen("aad.txt", "rb");
    
    for(;;){
        size_t a = fread(aadbuf, 1, 1024, aad_f);
        lenbuf = int(a);
        
        if (lenbuf <= 0) break;
        EVP_CipherUpdate(ctx, NULL, &unused, aadbuf, lenbuf);
     }
    /* Input text */
    for(;;){
        size_t a = fread(inbuf, 1, 1024, in);
        inlen = int(a);
        if (inlen <= 0) break;
        EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen);
        fwrite(outbuf, 1, outlen, out);
        }
    
    EVP_CipherFinal_ex(ctx, outbuf, &outlen);
    EVP_CIPHER_CTX_free(ctx);
    fwrite(outbuf, 1, outlen, out);
    
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)){
         cout << "error get tag" << endl;
         return 0;
   }
        FILE * tag_f = fopen("tag.txt", "wb");
        fwrite(tag, 1, sizeof(tag), tag_f);
        cout << tag << endl;
    }
    return 0;
    
    }

그런데 왜? 다른 모든 EVP 기능은 잘 작동합니다. 내가 뭘 그리워? 다른 기능을 호출해야합니까? 태그 대신 @ \ 267 *이 tag.txt 파일에 기록되었습니다.

답변

Topaco Sep 01 2020 at 23:30

코드에는 두 가지 버그가 있습니다.

  • sizeofIV의 길이를 결정하는 데 사용 되므로 0- 종결 자도 계산되고 잘못된 길이 13이 결정됩니다. 대신 sizeof, strlen올바른 값 (12)을 반환, 적용해야합니다.
  • 태그가 결정되기 전에 상황, 즉이 해제 EVP_CIPHER_CTX_free되기 전에 호출된다 EVP_CIPHER_CTX_ctrl. 이 순서는 취소되어야합니다.

이러한 변경으로 올바른 암호문과 태그가 생성됩니다.

고정 키 / IV 쌍은 테스트에만 사용할 수 있습니다. 실제로 키 / IV 쌍은 특히 GCM의 경우 한 번만 사용할 수 있습니다.