Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
421 views
in Technique[技术] by (71.8m points)

c - Non-printable character after generating random n-byte Base64 string

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]=''; // Null terminate

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

    return EXIT_SUCCESS;
}

Compiling and running with gcc rand_str.c -lcrypto && ./a.out | tail -1, sometimes produces something like:

I6YaDVSRPw5Ux+2paY4u4ToMKtZXQoBj`?

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

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


What do I need to do differently?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

BIO_write(bio, buffer, strlen(buffer));

NUL is a valid random byte, so that strlen will sometimes return less than the desired value (32).

The `? is due to the base64 buffer not having a NUL terminator, so it's reading out some random garbage. I don't know of any way to force OpenSSL to add a NUL, but you can tell printf where to stop:

(void)printf("Return value of the operation was: %d %.44s ", ret, base64EncodeOutput);


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...