首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BIO不刷新OpenSSL中的数据

BIO不刷新OpenSSL中的数据
EN

Stack Overflow用户
提问于 2020-08-07 06:37:41
回答 1查看 293关注 0票数 1

我使用BIO来使用OpenSSL计算某个文件的摘要。我的代码如下:

代码语言:javascript
复制
#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中找不到任何东西。

为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-13 16:30:50

BIO链接机制用于将BIO预先筛选到源/接收器BIO。它不是为将源BIO与接收器BIO连接起来而设计的。

所以你能做的是:

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

但你不能做的是:

  • 创建一个BIO链,该链以源开始,以带过滤器的接收器结束。没有自动将数据从源“泵”到接收器的机制。

另一个注意事项:BIO_f_md是一个筛选器BIO,它计算通过它传递的数据的摘要,但它不修改数据。因此,BIO的输出是原始数据,而不是数据摘要。在使用BIO_get_md (参考文献)处理了所有数据之后,可以检索摘要。因此,在您的示例中,即使支持将源链接到接收器,最终的dgst.txt也只包含来自test.txt的原始数据。

要修复您的示例,有两种方法:

方法1

使用摘要BIO创建一个链,然后是输入文件的源BIO。然后,我们可以从摘要BIO中读取数据,它内部从源BIO中提取数据。我们读取数据并立即丢弃它,直到处理完完整的文件为止。然后,我们可以从摘要BIO中检索摘要。

代码语言:javascript
复制
    // 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将丢弃数据。处理完所有数据后,我们可以从摘要BIO检索摘要。

代码语言:javascript
复制
    // 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); 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63296500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档