随机产生n字节的Base64串之后的非打印字符 [英] Non-printable character after generating random n-byte Base64 string

查看:411
本文介绍了随机产生n字节的Base64串之后的非打印字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用OpenSSL生成一个32字节的base64字符串,但它并不总是产生32字节的字符串,有时候输出是乱码,而不是正确地显示

I was trying to generate a 32byte base64 string using openssl, but it does not always produce 32 byte string and sometimes the output is garbled and not displayed correctly

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

int Base64Encode(const unsigned char* buffer, unsigned char** b64text) { //Encodes a binary safe base 64 string
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
    BIO_write(bio, buffer, strlen(buffer));
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    BIO_set_close(bio, BIO_NOCLOSE);
    BIO_free_all(bio);

    *b64text=bufferPtr->data;

    return (0); //success
}

int main() {
    unsigned char buffer[35], *base64EncodeOutput;
    int ret = RAND_bytes(buffer, 32);
    buffer[32]='\0'; // Null terminate

    (void)Base64Encode(buffer, &base64EncodeOutput);
    (void)printf("Return value of the operation was: %d\n%s\n", ret, base64EncodeOutput);

    return EXIT_SUCCESS;
}

编译和 GCC rand_str.c -lcrypto和放大器运行;&安培; ./a.out |尾-1 ,有时会产生这样的:

I6YaDVSRPw5Ux + 2paY4u4ToMKtZXQoBj`

有时输出并不长,甚至32个字节。

And sometimes the output is not even 32 bytes in length.

我的目标是复制这个命令做什么:
的OpenSSL兰特-base64 32

My goal is to replicate what this command does: openssl rand -base64 32

什么我需要做不同?

推荐答案

由于上面贴的解决方案,我能解决这个问题。下面是结果:

Thanks to the solutions posted above, I was able to fix this problem. Here is the result:

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

static char* base64_bytes(int size) {
    char *buff = malloc(size + 1), *bytes = NULL;
    int chunk;
    BIO *b64, *out;
    BUF_MEM *bptr;

    // Create a base64 filter/sink
    if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
        return NULL;
    }

    // Create a memory source
    if ((out = BIO_new(BIO_s_mem())) == NULL) {
        return NULL;
    }

    // Chain them
    out = BIO_push(b64, out);
    BIO_set_flags(out, BIO_FLAGS_BASE64_NO_NL);

    // Generate random bytes
    if (!RAND_bytes(buff, size)) {
        return NULL;
    }

    // Write the bytes
    BIO_write(out, buff, size);
    BIO_flush(out);

    // Now remove the base64 filter
    out = BIO_pop(b64);

    // Write the null terminating character
    BIO_write(out, "\0", 1);
    BIO_get_mem_ptr(out, &bptr);

    // Allocate memory for the output and copy it to the new location
    bytes = malloc(bptr->length);
    strncpy(bytes, bptr->data, bptr->length);

    // Cleanup
    BIO_set_close(out, BIO_CLOSE);
    BIO_free_all(out);
    free(buff);

    return bytes;
}

int main() {
    char *b64 = base64_bytes(32);
    puts(b64);

    free(b64);

    return EXIT_SUCCESS;
}


我原来尝试的主要问题是,当空终止通过的base64 过滤器,它不被识别为字符串的结束,而是被转换为Base64这使得字符串看它在原来的职位做的那样。


The main issue with my original attempt was that when the null terminator is passed through the base64 filter, it is not recognized as the end of the string, but rather it is converted to base64 which makes the string look the way it did in my original post.

因此​​,建议的解决方案是从 BIO删除的base64过滤器写原始字符串后,这则只保留了退出 BIO。因为退出 BIO是一个简单的接收器,我们可以写pretty任何东西给它,它不会修改它的输入。所以这给写一个空终止进入基础缓冲区和检索完整的字符串以后的机会。

So the suggested solution is to remove the base64 filter from the BIO after writing the original string, this then leaves just the out BIO. Since the out BIO is simply a sink, we can write pretty much anything to it and it does not modify it's input. So this gives the opportunity to write a null terminator into the underlying buffer and retrieve the complete string later.

这篇关于随机产生n字节的Base64串之后的非打印字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆