Last active
May 13, 2024 07:45
-
-
Save barrysteyn/4409525 to your computer and use it in GitHub Desktop.
Base64 Encoding/Decoding with the OpenSSL c api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Decodes Base64 | |
#include <openssl/bio.h> | |
#include <openssl/evp.h> | |
#include <string.h> | |
#include <stdio.h> | |
int calcDecodeLength(const char* b64input) { //Calculates the length of a decoded base64 string | |
int len = strlen(b64input); | |
int padding = 0; | |
if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are = | |
padding = 2; | |
else if (b64input[len-1] == '=') //last char is = | |
padding = 1; | |
return (int)len*0.75 - padding; | |
} | |
int Base64Decode(char* b64message, char** buffer) { //Decodes a base64 encoded string | |
BIO *bio, *b64; | |
int decodeLen = calcDecodeLength(b64message), | |
len = 0; | |
*buffer = (char*)malloc(decodeLen+1); | |
FILE* stream = fmemopen(b64message, strlen(b64message), "r"); | |
b64 = BIO_new(BIO_f_base64()); | |
bio = BIO_new_fp(stream, BIO_NOCLOSE); | |
bio = BIO_push(b64, bio); | |
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer | |
len = BIO_read(bio, *buffer, strlen(b64message)); | |
//Can test here if len == decodeLen - if not, then return an error | |
(*buffer)[len] = '\0'; | |
BIO_free_all(bio); | |
fclose(stream); | |
return (0); //success | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Encodes Base64 | |
#include <openssl/bio.h> | |
#include <openssl/evp.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <math.h> | |
int Base64Encode(const char* message, char** buffer) { //Encodes a string to base64 | |
BIO *bio, *b64; | |
FILE* stream; | |
int encodedSize = 4*ceil((double)strlen(message)/3); | |
*buffer = (char *)malloc(encodedSize+1); | |
stream = fmemopen(*buffer, encodedSize+1, "w"); | |
b64 = BIO_new(BIO_f_base64()); | |
bio = BIO_new_fp(stream, BIO_NOCLOSE); | |
bio = BIO_push(b64, bio); | |
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line | |
BIO_write(bio, message, strlen(message)); | |
BIO_flush(bio); | |
BIO_free_all(bio); | |
fclose(stream); | |
return (0); //success | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
int main() { | |
//Encode To Base64 | |
char* base64EncodeOutput; | |
Base64Encode("Hello World", &base64EncodeOutput); | |
printf("Output (base64): %s\n", base64EncodeOutput); | |
//Decode From Base64 | |
char* base64DecodeOutput; | |
Base64Decode("SGVsbG8gV29ybGQ=", &base64DecodeOutput); | |
printf("Output: %s\n", base64DecodeOutput); | |
return(0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -o base64 Main.c Base64Encode.c Base64Decode.c -lcrypto -lm |
this decode do not work when provided with an ssh key to decode
Helpful note: To make this work across platforms that don't support fmemopen
, a BIO_new(BIO_s_mem())
can be used as the output.
Example for encoding (uses C++, but you get the idea) - in this case, rand
is the input to be encoded.
BIO *b64 = BIO_new(BIO_f_base64());
BIO *bio = BIO_new(BIO_s_mem());
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
BIO_write(bio, rand, bytes_amt);
BIO_flush(bio);
// Convert the encoded data to a C-string
BUF_MEM *bptr;
BIO_get_mem_ptr(bio, &bptr);
std::string data_str(bptr->data, bptr->length);
@emctague Thanks for that. I'm surprised you can use BIO_get_mem_ptr
on a BIO_f_base64
instance (bio is set to b64 after the BIO_push
call). But this works when I try it.
For anyone else, BIO_s_mem
and related require including openssl/buffer.h
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
if strlen(b64input) == 0 or 1 calcDecodeLength may be crash
BIO_flush(bio); g++ ouputs “value computed is not used” warnning
should change into (void)BIO_flush(bio);