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
This entry was posted in programming and tagged , ,

10 Comments

  1. ChaosCreator

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

  2. 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. offir

    Can you Plz publish a parallel function for Base64 decoding?

  4. Ha, I just noticed this now after
    figuring out myself how to do it:

    http://www.pixelbeat.org/programming/lib_crypto.html

    Referenced there is a small wrapper library
    around libcrypto that uses the same
    method you do for base64 encoding
    (the lib also has interfaces for digests,
    and symmetric and assymetric ciphers).
    Note my lib is a little more generalised,
    and also more robust in the case of memory exhaustion.

    cheers,
    Pádraig.

  5. Antonio

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

    thanks.

  6. 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

  7. 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.

  8. 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.

  9. 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;
    }

  10. 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;

One Trackback

  1. […] Someone asked for an example of decoding with OpenSSL on the Howto base64 encode with C/C++ and OpenSSL post. So here it is: #include <string.h> […]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>