Howto base64 encode with C/C++ and OpenSSL

I've been doing a little C programming lately and I have found that if you have a up to date distribution of linux there are a lot of libraries out there that make doing things you do in other languages like java easier.

As I have time I'm going to post some examples of what I have found. The first here is how to base64 encode a chunk of memory using OpenSSL.

#include <string.h>

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

char *base64(const unsigned char *input, int length);

int main(int argc, char **argv)
{
  char *output = base64("YOYO!", sizeof("YOYO!"));
  printf("Base64: *%s*\n", output);
  free(output);
}

char *base64(const unsigned char *input, int length)
{
  BIO *bmem, *b64;
  BUF_MEM *bptr;

  b64 = BIO_new(BIO_f_base64());
  bmem = BIO_new(BIO_s_mem());
  b64 = BIO_push(b64, bmem);
  BIO_write(b64, input, length);
  BIO_flush(b64);
  BIO_get_mem_ptr(b64, &bptr);

  char *buff = (char *)malloc(bptr->length);
  memcpy(buff, bptr->data, bptr->length-1);
  buff[bptr->length-1] = 0;

  BIO_free_all(b64);

  return buff;
}

And to compile this just use the following command:

cc -o base64 base64.c -lssl

11 thoughts on “Howto base64 encode with C/C++ and OpenSSL

  1. ChaosCreator

    thanks for the code , but can you try to compile your code next time before you release it ????

  2. carson Post author

    Sorry about that. I believe somewhere along the line an upgrade to the blog software converted some of the code into html. It should be good now.

  3. Pingback: Howto base64 decode with C/C++ and OpenSSL @ IONCANNON

  4. Antonio

    Hi.
    I tested your program and it good i like.
    Do you have one example to sign a document with openSSL ?

    thanks.

  5. Subra

    Hey Carson,

    Thanks for the code. But do you have any idea as to why ur function base64 adds a newline ('\n') character at the end of the string.

    Similarly, ut base64 decode function expects a newline character at the end.

    Thanks

  6. Amit

    Hi Subra,

    base64 algorithm in itself appends a carriage return and linefeed characters after its 'linesize' character and at the end of the test to be encoded. This infact increases the length of the encoded string by about 3%, but this cannot be avoided.

  7. Jon Scobie

    I think you'll find that you should be using strlen("YOYO!") not sizeof as that will return a completely different answer. If you test with "uuencode -m" or "openssl enc" you will see what I mean.

  8. Bill

    /*
    ** returns the length of the b64 decoded buffer, outbuf is set to a pointer
    ** to new memory containing the result. This will be null terminated with
    ** an extra byte.
    **
    ** Caller must free the returned string pointed to in outbuf.
    */
    int base64d(const unsigned char *input, int length, char **outbuf) {

    BIO *bio, *b64, *bmem, *decoder;
    char inbuf[512];
    int inlen, readlen = -1;
    BUF_MEM *bptr;
    char * buffer;

    bmem = BIO_new_mem_buf(input, length);
    b64 = BIO_new(BIO_f_base64());
    /* decoder = BIO_new(BIO_s_mem()); */

    decoder = BIO_push(b64, bmem);
    /* BIO_push(decoder, b64); */

    BIO_flush(decoder);
    BIO_get_mem_ptr(decoder, &bptr);

    if (buffer = (char *)malloc(length)) {
    readlen = BIO_read(decoder, buffer, length);
    buffer[readlen] = 0;
    }

    BIO_free_all(decoder);

    *outbuf = buffer;
    return readlen;
    }

  9. trulyliu

    There is a minor mistake in your code:

    char *buff = (char *)malloc(bptr->length +1);
    memcpy(buff, bptr->data, bptr->length);
    buff[bptr->length] = 0;

Leave a Reply

Your email address will not be published. Required fields are marked *