gpt4 book ai didi

c++ - BIO不会在OpenSSL中刷新数据

转载 作者:行者123 更新时间:2023-12-02 10:11:42 24 4
gpt4 key购买 nike

我正在使用BIO使用OpenSSL计算某些文件的摘要。我的代码如下:

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/bio.h>

int main(){

BIO* bio_infile;
bio_infile = BIO_new_file("test.txt", "rb");

BIO* bio_md = BIO_new(BIO_f_md());
BIO_set_md(bio_md, EVP_sha1());

BIO* bio_outfile;
bio_outfile = BIO_new_file("dgst.txt","w");

BIO_push(bio_md, bio_outfile);
BIO_push(bio_infile, bio_md);

BIO_flush(bio_infile);
BIO_flush(bio_md);

BIO_free(bio_infile);
BIO_free(bio_md);
BIO_free(bio_outfile);

return 0;
}
但是,当我的程序用完时,我在文件 dgst.txt中什么也找不到。
为什么?

最佳答案

BIO链接机制旨在将过滤器BIO前置在源/接收器BIO上。它不是为将源BIO与接收器BIO连接而设计的。
因此,您可以做什么:

  • 创建带有最终BIO接收器的过滤器的BIO链。将数据写入链的头部时,输入将遍历每个过滤器,直到到达接收器为止。
  • 创建带有最终BIO源的过滤器的BIO链。从链的头读取数据时,读取请求将沿着链传递到源。从源读取的数据随后将通过每个过滤器以相反的方向遍历链。

  • 但是你不能做的是:
  • 创建一个BIO链,该链从源头开始到以接收器结束,中间有过滤器。没有机制可以将数据从源自动“泵送”到接收器。

  • 另一个注意事项: BIO_f_md是一个过滤器 BIO,它计算通过它的数据的摘要,但不会修改数据。因此 BIO的输出是原始数据,而不是数据摘要。在使用 BIO_get_md( reference)处理了所有数据之后,可以检索摘要。因此,在您的示例中,即使支持将源链接到接收器,最终的 dgst.txt也将仅包含 test.txt的原始数据。
    要修正您的示例,有两种方法:
    方法1
    使用摘要 BIO和输入文件的源 BIO创建一个链。然后,我们可以从摘要 BIO中读取,该摘要在内部从源 BIO中提取数据。我们读取数据并立即将其丢弃,直到处理完整个文件为止。然后,我们可以从摘要 BIO中检索摘要。
        // Create chain: Digest -> Source File
    BIO* bio_infile;
    bio_infile = BIO_new_file("test.txt", "rb");

    BIO* bio_md = BIO_new(BIO_f_md());
    BIO_set_md(bio_md, EVP_sha1());

    BIO* head = BIO_push(bio_md, bio_infile);

    // Read from head of chain
    std::array<char,1024> buf{};
    int read;

    while ((read = BIO_read(head, buf.data(), buf.size())) > 0) {
    // Ignore buffer, we only want the data to pass throug the digest BIO
    }

    // Read result from digest BIO
    EVP_MD *md;
    BIO_get_md(bio_md, &md);

    std::array<char, EVP_MAX_MD_SIZE> md_buf{};
    int mdlen = BIO_gets(bio_md, md_buf.data(), md_buf.size());

    // Print digest to stdout
    for (int i = 0; i < mdlen; i++) {
    printf("%02x", static_cast<uint8_t>(md_buf[i]));
    }
    printf("\n");

    // Cleanup
    BIO_free_all(head);
    方法2
    使用摘要 BIO和一个特殊的接收器 BIO创建一个链,以丢弃数据( BIO_s_null)。然后,我们从源 BIO读取输入文件的数据(没有任何链接),并将数据写入摘要 BIO。写入的数据通过摘要 BIO传递到接收器 BIO,后者将丢弃数据。处理完所有数据后,我们可以从摘要 BIO中检索摘要。
        // Create chain: Digest -> Null Sink
    BIO* bio_infile;
    bio_infile = BIO_new_file("test.txt", "rb");

    BIO* bio_md = BIO_new(BIO_f_md());
    BIO_set_md(bio_md, EVP_sha1());

    BIO* bio_null = BIO_new(BIO_s_null());

    BIO* head = BIO_push(bio_md, bio_null);

    // Read from file and write to chain
    std::array<char,1024> buf{};
    int read;

    while ((read = BIO_read(bio_infile, buf.data(), buf.size())) > 0) {
    BIO_write(head, buf.data(), read);
    }

    // Read result from digest BIO
    EVP_MD *md;
    BIO_get_md(bio_md, &md);

    std::array<char, EVP_MAX_MD_SIZE> md_buf{};
    int mdlen = BIO_gets(bio_md, md_buf.data(), md_buf.size());

    // Print digest to stdout
    for (int i = 0; i < mdlen; i++) {
    printf("%02x", static_cast<uint8_t>(md_buf[i]));
    }
    printf("\n");

    // Cleanup
    BIO_free(bio_infile);
    BIO_free_all(head);

    关于c++ - BIO不会在OpenSSL中刷新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63296500/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com