Created
September 7, 2017 19:55
-
-
Save luelista/7f302fc26aab67aa1095de285e46e0fb to your computer and use it in GitHub Desktop.
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 <openssl/blowfish.h> | |
#include <openssl/md5.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <inttypes.h> | |
#define TOKENS "\r \n " | |
#define DIRECTION 1 | |
#define SRCDATA 2 | |
#define ARGS 3 | |
// key tuda 4e2e6a296a51494f5230383b646123752233622b4771227b403c407969 | |
// key uhh 422a752c73625a217b517a534c496329735551483b35615b6752512423 | |
int base64decode (char *in, size_t inLen, unsigned char *out, size_t *outLen); | |
int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize); | |
static const char translate_a[] = "ipkIBozSlL8CVH3J7PvQfWYuemxOcR4rn5bgDUqMaKXTy60h9wt-NZdjFAE12Gs."; | |
static const char translate_b[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
void translate(char* mystr, const char* tab_a, const char*tab_b); | |
int main(int argc, char **argv) { | |
char ciphertext[1024*1024]; | |
char plaintext[1024*1024]; | |
char ivec[]={30, 214, 186, 72, 38, 84, 2, 16}; | |
char byte; | |
char *tok; | |
unsigned char digest[MD5_DIGEST_LENGTH]; | |
size_t len = sizeof(ciphertext); | |
size_t olen = sizeof(plaintext); | |
BF_KEY key; | |
if( argc != ARGS ) | |
return 1; | |
char *thekey="422a752c73625a217b517a534c496329735551483b35615b6752512423"; | |
BF_set_key(&key, strlen(thekey), thekey); | |
int num = 0; | |
if (argv[DIRECTION][0] == 'e') { | |
len = strlen(argv[SRCDATA]); | |
MD5(argv[SRCDATA], len, digest); | |
for(int i=0; i<MD5_DIGEST_LENGTH; i++) sprintf(plaintext+i*2,"%02X",digest[i]); | |
plaintext[MD5_DIGEST_LENGTH*2] = ','; | |
strcpy(&plaintext[MD5_DIGEST_LENGTH*2+1], argv[SRCDATA]); | |
len += MD5_DIGEST_LENGTH*2 + 1; | |
printf("with digest: %s\n",plaintext); | |
BF_cfb64_encrypt(plaintext, ciphertext, len, &key, ivec, &num, BF_ENCRYPT); | |
base64encode(ciphertext, len, plaintext, olen); | |
translate(plaintext, translate_b, translate_a); | |
} else { | |
translate(argv[SRCDATA], translate_a, translate_b); | |
base64decode(argv[SRCDATA], strlen(argv[SRCDATA]), ciphertext, &len); | |
BF_cfb64_encrypt(ciphertext, plaintext, len, &key, ivec, &num, BF_DECRYPT); | |
} | |
printf("%s\n", plaintext); | |
return 0; | |
} | |
void translate(char* mystr, const char* tab_a, const char*tab_b) { | |
for(int i=strlen(mystr); i>=0; i--) { | |
char* p = strchr(tab_a, mystr[i]); | |
if (p!=NULL) mystr[i] = tab_b[p-tab_a]; | |
} | |
} | |
#define WHITESPACE 64 | |
#define EQUALS 65 | |
#define INVALID 66 | |
static const unsigned char d[] = { | |
66,66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53, | |
54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28, | |
29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, | |
66,66,66,66,66,66 | |
}; | |
int base64decode (char *in, size_t inLen, unsigned char *out, size_t *outLen) { | |
char *end = in + inLen; | |
char iter = 0; | |
uint32_t buf = 0; | |
size_t len = 0; | |
while (in < end) { | |
unsigned char c = d[*in++]; | |
switch (c) { | |
case WHITESPACE: continue; /* skip whitespace */ | |
case INVALID: return 1; /* invalid input, return error */ | |
case EQUALS: /* pad character, end of data */ | |
in = end; | |
continue; | |
default: | |
buf = buf << 6 | c; | |
iter++; // increment the number of iteration | |
/* If the buffer is full, split it into bytes */ | |
if (iter == 4) { | |
if ((len += 3) > *outLen) return 1; /* buffer overflow */ | |
*(out++) = (buf >> 16) & 255; | |
*(out++) = (buf >> 8) & 255; | |
*(out++) = buf & 255; | |
buf = 0; iter = 0; | |
} | |
} | |
} | |
if (iter == 3) { | |
if ((len += 2) > *outLen) return 1; /* buffer overflow */ | |
*(out++) = (buf >> 10) & 255; | |
*(out++) = (buf >> 2) & 255; | |
} | |
else if (iter == 2) { | |
if (++len > *outLen) return 1; /* buffer overflow */ | |
*(out++) = (buf >> 4) & 255; | |
} | |
*outLen = len; /* modify to reflect the actual output size */ | |
return 0; | |
} | |
int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) | |
{ | |
const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
const uint8_t *data = (const uint8_t *)data_buf; | |
size_t resultIndex = 0; | |
size_t x; | |
uint32_t n = 0; | |
int padCount = dataLength % 3; | |
uint8_t n0, n1, n2, n3; | |
/* increment over the length of the string, three characters at a time */ | |
for (x = 0; x < dataLength; x += 3) | |
{ | |
/* these three 8-bit (ASCII) characters become one 24-bit number */ | |
n = ((uint32_t)data[x]) << 16; //parenthesis needed, compiler depending on flags can do the shifting before conversion to uint32_t, resulting to 0 | |
if((x+1) < dataLength) | |
n += ((uint32_t)data[x+1]) << 8;//parenthesis needed, compiler depending on flags can do the shifting before conversion to uint32_t, resulting to 0 | |
if((x+2) < dataLength) | |
n += data[x+2]; | |
/* this 24-bit number gets separated into four 6-bit numbers */ | |
n0 = (uint8_t)(n >> 18) & 63; | |
n1 = (uint8_t)(n >> 12) & 63; | |
n2 = (uint8_t)(n >> 6) & 63; | |
n3 = (uint8_t)n & 63; | |
/* | |
* if we have one byte available, then its encoding is spread | |
* out over two characters | |
*/ | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex++] = base64chars[n0]; | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex++] = base64chars[n1]; | |
/* | |
* if we have only two bytes available, then their encoding is | |
* spread out over three chars | |
*/ | |
if((x+1) < dataLength) | |
{ | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex++] = base64chars[n2]; | |
} | |
/* | |
* if we have all three bytes available, then their encoding is spread | |
* out over four characters | |
*/ | |
if((x+2) < dataLength) | |
{ | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex++] = base64chars[n3]; | |
} | |
} | |
/* | |
* create and add padding that is required if we did not have a multiple of 3 | |
* number of characters available | |
*/ | |
if (padCount > 0) | |
{ | |
for (; padCount < 3; padCount++) | |
{ | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex++] = '='; | |
} | |
} | |
if(resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ | |
result[resultIndex] = 0; | |
return 0; /* indicate success */ | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment