gpt4 book ai didi

c - OpenSSL BIO_f_base64 不读取整个缓冲区

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:47 26 4
gpt4 key购买 nike

我正在尝试读取文件并对其进行 base64 解码。由于某种原因,OpenSSL 只读取它的一部分,然后在所有后续调用中它只返回 0。这是我正在使用的代码:

#include <stdio.h>
#include <stdlib.h>

#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>

size_t b64_get_datalen(const char* b64, size_t b64len) {
size_t actual_len = 0;
int padding = 0;

for (int i = 0; i < b64len; i++) {
if (b64[i] != '\n') actual_len++;
}

int last = b64len-1;
if (b64[last] == '\n') {
last--;
}
if (b64[last] == '=') {
padding = b64[last-1] == '=' ? 2 : 1;
}

return (actual_len*3)/4 - padding;
}


int main(int argc, char** argv) {
FILE* fp = fopen("7.txt", "r");
if (fp == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}

fseek(fp, 0, SEEK_END);
size_t b64_len = ftell(fp);
rewind(fp);

char b64[b64_len];
fread(b64, b64_len, 1, fp);
fclose(fp);

size_t data_len = b64_get_datalen(b64, b64_len);
char data[data_len];

BIO *bio, *base64;
base64 = BIO_new(BIO_f_base64());
bio = BIO_new_mem_buf(b64, -1);
bio = BIO_push(base64, bio);

int read = BIO_read(bio, data, b64_len);
printf("expected %d bytes, got %d bytes\n", (int)data_len, (int)read);
BIO_free_all(bio);
}

程序输出:expected 2880 bytes, got 2244 bytes

我试图读取的文件来自 cryptopals challenges ( http://cryptopals.com/static/challenge-data/7.txt )。我用 Python 解决了这个挑战,读取和 base64 解码文件没有问题。

这种行为的原因是什么?还有一个更普遍的问题,应该如何使用 OpenSSL 调试此类问题?

最佳答案

问题出在这一行:

bio = BIO_new_mem_buf(b64, -1);

来自 BIO_new_mem_buf 的手册页:

https://www.openssl.org/docs/man1.1.0/crypto/BIO_s_mem.html

BIO_new_mem_buf() creates a memory BIO using len bytes of data at buf, if len is -1 then the buf is assumed to be nul terminated and its length is determined by strlen.

但是你已经传递了 -1 并且你的缓冲区没有被 nul 终止!因此 strlen 将溢出缓冲区并继续运行,直到找到 nul 终止符。这可能包含许多不是有效 base64 的值,因此 base64 解码失败。

似乎 BIO_f_base64() BIO 的行为是读取并返回它已成功读取的内容,但一旦遇到错误就放弃尝试继续读取 - 相反整个阅读失败。我不清楚这是预期行为还是错误。

And a more general question, how one should debug such issues with OpenSSL?

一般来说,您应该检查 OpenSSL 错误堆栈,它通常会提供有关问题来源的良好信息。例如通过使用 ERR_print_errors_fp():

https://www.openssl.org/docs/man1.1.0/crypto/ERR_print_errors_fp.html

并不是说它对这个特定问题有帮助,因为似乎没有错误被放置在这个问题的错误堆栈上。

关于c - OpenSSL BIO_f_base64 不读取整个缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48537964/

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