#include #include #include #include #include "md5.h" #define min_t(type,x,y) \ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) static const char *hstr = "0123456789ABCDEF"; typedef struct { size_t len; char *buf; } string_t; #define s_buf(x) ((x)->buf) #define s_len(x) ((x)->len) static inline void set_str(string_t *s, void *buf, int len) { s_buf(s) = buf; s_len(s) = len; } static inline void add_str(string_t *a, string_t *b) { memcpy(s_buf(a) + s_len(a), s_buf(b), s_len(b)); s_len(a) += s_len(b); } static void pack_h(string_t *src, string_t *dst, int bytes_of_src) { int count, i; char *s, *d; if (!src || !s_buf(src) || !dst) { fprintf(stderr, "%s(): -.-;\n", __func__); return; } count = min_t(int, bytes_of_src, s_len(src)); set_str(dst, realloc(s_buf(dst), count * 2), 0); s = s_buf(src); d = s_buf(dst); for (i = 0; i < count; i++) { int a = *s++ & 0xff; *d++ = *(hstr + (a >> 4)); *d++ = *(hstr + (a & 0xf)); } s_len(dst) = count * 2; } static void bytexor(string_t *src, string_t *dst, string_t *key, int len) { int i; unsigned char *s, *d, *k; int count; count = len; count = min_t(int, s_len(src), count); count = min_t(int, s_len(dst), count); count = min_t(int, s_len(dst), count); s = (unsigned char*)s_buf(src); d = (unsigned char*)s_buf(dst); k = (unsigned char*)s_buf(key); for (i = 0; i < count; i++) { *d++ = *s++ ^ *k++; } } static int crypt_md5(const char *_msg, int msglen, const char *_key, char *tmp, int tmps) { string_t key, key1, key2; string_t buffer, dst, md; int left, this_len; int key_len; char md5buf[16]; /* char* -> string_t */ set_str(&md, &md5buf[0], 16); set_str(&dst, tmp, tmps); set_str(&key, (char*)_key, strlen(_key)); set_str(&buffer, NULL, 0); set_str(&key1, NULL, 0); set_str(&key2, NULL, 0); left = msglen; while (left) { this_len = min_t(int, 16, left); /* $key1 = $key.$key2.$buffer; */ key_len = s_len(&key) + s_len(&key2) + s_len(&buffer); set_str(&key1, realloc(s_buf(&key1), key_len), 0); add_str(&key1, &key); add_str(&key1, &key2); add_str(&key1, &buffer); /* $md = md5($key1); */ md5_buffer(s_buf(&key1), s_len(&key1), s_buf(&md)); /* $key2=pack("H*",$md); */ pack_h(&md, &key2, s_len(&md)); /* $buffer=substr($msg,0,16); */ set_str(&buffer, (char*)_msg, this_len); /* $str = bytexor($buffer,$key2); */ bytexor(&buffer, &dst, &key2, this_len); memcpy(s_buf(&dst), s_buf(&buffer), this_len); /* $string.=$str; */ set_str(&dst, s_buf(&dst) + this_len, s_len(&dst) - this_len); /* $msg=substr($msg,16); */ _msg += this_len; left -= this_len; } free(s_buf(&key1)); free(s_buf(&key2)); return s_buf(&dst) - tmp; } int main(int argc, char **argv) { char tmp_buf[256]; char tmp_buf2[256]; char *msg = "☆━2008년*♡*┐┃설날부턴 ° ː│。°더많이°│ː 。사랑할께~┃└*♡* *‥─━★"; char *key = "9857861"; int ret; printf("source len %d\n", strlen(msg)); ret = crypt_md5(msg, strlen(msg), key, tmp_buf, sizeof(tmp_buf)); printf("encrypted len %d\n", ret); #if 1 ret = crypt_md5(tmp_buf, ret, key, tmp_buf2, sizeof(tmp_buf2)); printf("decrypted len %d\n", ret); tmp_buf2[ret] = 0; printf("result: %s\n", tmp_buf2); #endif return 0; }