Base64 encoding\decoding

Started by Vortex, February 23, 2025, 08:17:07 PM

Previous topic - Next topic

Vortex

Here is an example using cryptographic API functions to encode to base64 format and decode the result :

.386
.model flat,stdcall
option casemap:none

include     Base64.inc

.data

MyStr       db 'This is a test.',0
m1          db 'String MyStr converted to base64 = ',0
m2          db 13,10,'Base64 data BinData converted to string = ',0
binSize     dd STRING_SIZE
MyStr2size  dd STRING_SIZE

.data?

BinData     db STRING_SIZE dup(?)
MyStr2      db STRING_SIZE dup(?)

.code

start:

    invoke  lstrlen,ADDR MyStr
    invoke  CryptBinaryToString,ADDR MyStr,eax,\
            CRYPT_STRING_BASE64,ADDR BinData,\
            ADDR binSize

    invoke  StdOut,ADDR m1
    invoke  StdOut,ADDR BinData

    invoke  CryptStringToBinary,ADDR BinData,0,\
            CRYPT_STRING_BASE64,ADDR MyStr2,\
            ADDR MyStr2size,0,0

    invoke  StdOut,ADDR m2
    invoke  StdOut,ADDR MyStr2

    invoke  ExitProcess,eax

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

StdOut PROC _string:DWORD

    sub     esp,2*4
   
    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov     DWORD PTR [esp+4],eax
   
    invoke  lstrlen,DWORD PTR [esp+12]
    mov     edx,esp
   
    invoke  WriteFile,DWORD PTR [esp+20],\
            DWORD PTR [esp+24],\
            eax,edx,0
           
    add     esp,2*4
    retn    4

StdOut ENDP

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

END start
Code it... That's all...

John Z

Hi Vortex,

This is very interesting, and coincidentally, I just ran across the crypto section of the API.  Before this week I had no idea such a thing existed.   While I learned a lot by writing my own Base64 encode/decode routines I see using the API would be simpler and probably run faster although I must say mine is no slow poke.

Thanks,

John Z

Vortex

#2
Hi John,

This the C code obtained from the BCX converter :

#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "crypt32.lib")

#define STRSIZE 512

static char    BinData[STRSIZE];
static char    MyStr[STRSIZE];
static char    MyStr2[STRSIZE];
static DWORD   binSize=STRSIZE;
static DWORD   MyStr2size=STRSIZE;

int main(int argc, char *argv[])
{
  strcpy(MyStr,"This is a test.");
  CryptBinaryToString((const unsigned char*)MyStr,(int)strlen(MyStr),CRYPT_STRING_BASE64,(char*)BinData, &binSize);
  printf("%s%s\n","String MyStr converted to base64 = ",BinData);
  CryptStringToBinary(BinData,0,CRYPT_STRING_BASE64,(unsigned char*)&MyStr2, &MyStr2size,0,0);
  printf("%s%s\n","Base64 data BinData converted to string = ",MyStr2);
  return EXIT_SUCCESS;   // End of main program
  }
Code it... That's all...

TimoVJL

Long time ago there was need for base64 conversion, but at that time have to support Windows 9* and AIX for SMTP too.
Windows XP with this or CDOSys made things easier.
May the source be with you

Vortex

Hi Timo,

The Windows tool certutil can do base64 coding \ encoding.
Code it... That's all...

John Z

#5
Thanks Vortex,
Quote from: Vortex on February 24, 2025, 10:07:21 AM
Hi John,
This the C code obtained from the BCX converter :

A slight flaw to catch the unaware in the above C example.  The output of CRYPT_STRING_BASE64 is a minimum of 33% larger than the input string.  Not a problem with converter code since the input string was so small. But for the example given if the input string was over 385 or so bytes - then buffer overrun.

John Z

Quin

Cool stuff, thanks for sharing Vortex! I really like this API, leave it to Microsoft to have base64 encoding/decoding hidden in their Win32 API. 8)