php->c 컨버팅 다시 한번 도와 주세요 ㅠ.ㅠ

mrbaen의 이미지

어제 글을 올려서많은 도움을 받고 차분하게 다시 나름(?)정리 해가면서 삽질을 했는데 하다가 또 막혔네요 ㅠ.ㅠ 도와주세요.
16자리씩 잘라서 비트 연산해서 암호화 하는건데
루프돌다가 4번째 부터 값이 틀려 지네요

php소스

<?
function bytexor($a,$b)
{
	//echo "a:/$a/ ||| b:/$b/\n";
	$c="";
	for($i=0;$i<16;$i++)
	{
		$d = $a{$i}^$b{$i};
		$c.=$d;
		//echo"buf$i:/$d/" . ord($d) . "\n";
 
	}
	return $c;
}
 
 
function decrypt_md5($msg,$key)
{
        $string="";
        $buffer="";
        $key2="";
 
        while($msg)
        {
                $key2=pack("H*",md5($key.$key2.$buffer));
                $buffer=bytexor(substr($msg,0,16),$key2);
                $string.=$buffer;
                $msg=substr($msg,16);
        }
        return($string);
}
 
function encrypt_md5($msg,$key)
{
        $string="";
        $buffer="";
        $key2="";
 
        while($msg)
        {
			$i++;
				//echo $key.$key2.$buffer;
				$key1 = $key.$key2.$buffer;
				echo "key1:/$key1/\n";
 
				$md = md5($key1);
				echo "md5:/$md/\n";
 
                $key2=pack("H*",$md);
				echo "key2:/$key2/\n";
 
                $buffer=substr($msg,0,16);
				echo "buffer:/$buffer/\n";
 
				$str = bytexor($buffer,$key2);
				echo "bytexor:/" . strlen($str) . "/$str/\n";
 
                $string.=$str;
				echo "ret_msg:/$string/\n";
 
                $msg=substr($msg,16);
				echo "msg:/$msg/\n";
				echo "\n\n";
        }
        return($string);
}
 
// 사용 예
$message = "☆━2008년*♡*┐┃설날부턴 ° ː│。°더많이°│ː 。사랑할께~┃└*♡* *‥─━★";
$key = "9857861";
 
$encrypted = encrypt_md5($message, $key);
$decrypted = decrypt_md5($encrypted, $key);
 
echo "msg = ".strlen($message) . "$message";
echo " \n";
echo "Encrypted = ".strlen($encrypted) . "/$encrypted/";
echo " \n";
echo "Decrypted = $decrypted";
echo " \n";
 
?>

컨버팅중인 C소스

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <netdb.h>
//#include "base64EnDecode.h" 
//#include "Crypt_EnDecode.h" 
#include <openssl/md5.h>
#include <sys/stat.h> 
#include <fcntl.h> 
 
char substr(char *ret , const char *txt, int sno , int eno)
{
	if (eno == 0) eno = strlen(txt) - sno;
	if (eno > (strlen(txt)-sno)) eno = strlen(txt) - sno;
	if (sno>strlen(txt))
	{
		strcpy(ret , "");
		return;	
	}
 
	char buffer1[eno+1] ;
	int i,j;
 
	strcpy(buffer1 , "");
 
	for (i=sno; i<(sno + eno);i++ )
	{
		sprintf(buffer1 , "%s%c" , buffer1 , txt[i]);
	}
 
	//printf("j:%d /1ret:/%s/ buffer1:/%s/ txt:/%s/\n" , j , ret , buffer1 , txt);
	strcpy(ret , buffer1);
	//printf("2ret:/%s/ buffer1:/%s/ txt:/%s/\n" , ret , buffer1 , txt);
}
 
static char x2b(char c)
{
	if(c>='0' && c<='9')
		return c-'0';
	else if (c>='A' && c<='F')
		return c-'A'+0xa;
	else if (c>='a' && c<='f')
		return c-'a'+0xa;
 
	return -1; // error
}
 
 
int bin2hex(char *buf, char *textbuf, int len, int type)
{
	char hexs[]="0123456789ABCDEF";
	int i;
	int j=0;
 
	for(i=0;i<len;i++)
	{
		textbuf[j++] = hexs[ (buf[i]>>4)&0x0f ];
		textbuf[j++] = hexs[ buf[i]&0x0f ];
		if(type==1 && (i+1 != len))
		{
			textbuf[j++] = ' ';	
		}
	}
	textbuf[j]=0;
}
 
 
 
int hex2bin( char *buf , char *hexstring , int maxbuf)
{
	//printf("buf:/%s/hexstring:/%s/maxbuf:/%d/\n" , buf , hexstring , maxbuf);
	char *pc=hexstring;
	int i=0;
	int	byte=-1; // -1 empty
	//printf("pc:/%s/hexstring:/%s/maxbuf:/%d/\n" , hexstring , hexstring , maxbuf);
 
	while(*pc!='\0' && i<maxbuf )
	{
		if( isxdigit(*pc) )
		{
			if(byte == -1)
			{
				byte = x2b(*pc);
			}
			else
			{
				buf[i] = byte<<4 | x2b(*pc);
				i++;
				byte = -1;
			}
		}
		else
		{
			if(byte != -1)
			{
				buf[i]= byte;
				i++;
				byte = -1;
			}
		}
	//printf("pc:/%s/ buf:/%s/ buflen:/%d/\n" , pc,buf , strlen(buf));
		pc++;
	}
 
	//printf("buf:/%s/hexstring:/%s/maxbuf:/%d/\n" , buf , hexstring , maxbuf);
	return i;
}
 
void bytexor(char *ret , const char *a, const char *b)
{
	//printf("a:%s b:%s\n" , a , b);
	char buf[100]="";
	int i;
 
	for(i = 0; i < 16; i++)
	{
		buf[i] = a[i] ^ b[i];
		//printf("cc:%d/i:%d/%d\n" ,strlen(buf),i,buf[i]);
//		buf = tmp;
	}
	//strcpy(tmp , substr(buf , 0,16));
	strcpy(ret , buf);
}
char *MD5_Encrypt(char *_md5 , char *msg)
{
	char lsBuff[strlen(msg)];
	unsigned char lucpMD5[16] = "";
	unsigned char ret[16] = "";
	unsigned long lulLen = strlen(msg);
	int li;
 
	strcpy (lsBuff,msg);
 
	MD5_CTX lmdContext;
 
	MD5_Init(&lmdContext);
	MD5_Update(&lmdContext,lsBuff,lulLen);
	MD5_Final(lucpMD5, &lmdContext);
 
	for(li=0;li<16;li++)
	{
		//printf("%02x",lucpMD5[li]);
		sprintf(ret , "%s%02x" , ret , lucpMD5[li]);
		//printf("aa%d:%s\n" , li,ret);
	}
	strcpy(_md5 , ret);
	//printf("ret:%s\n",_md5);
}
 
void Hpack(char *key2 , char *key1)
{
	char _md5[100]="";
 
	MD5_Encrypt(_md5 , key1);
	printf("md:/%s/\n" , _md5);
 
	//printf("20:/%s/\n" , key2);
	hex2bin(key2 , _md5 , 16);
	//printf("21:/%s/\n" , key2);
}
 
char encrypt_md5(char *ret_msg , char *msg , char *key)
{
	char key1[100] = "";
	char key2[17] = "";
	char msg1[2000] = "";
	char buffer[17] = "";
	char buf[17] = "";
	char tmp[2000] = "";
 
	strcpy(msg1 , msg);
 
	while(strlen(msg1)>0)
	{
/*
                $key2=pack("H*",md5($key.$key2.$buffer));
                $buffer=substr($msg,0,16);
                $string.=bytexor($buffer,$key2);
                $msg=substr($msg,16);
*/
 
 
		sprintf(key1 , "%s%s%s" , key,key2,buffer);
		printf("key1:/%s/\n" , key1);
 
		Hpack(key2 , key1);
		printf("key2:/%s/\n" , key2);
 
		substr(buffer , msg1, 0,16);
		printf("buffer1:%s\n" , buffer);
 
		bytexor(buf , buffer , key2);
		printf("bytexor:/%d/%s/\n" , strlen(buf),buf);
 
		sprintf(ret_msg , "%s%s" , ret_msg , buf);
		printf("ret_msg:/%s/\n" , ret_msg);
 
		substr(msg1 , msg1 , 16,0);
		printf("msg:%s/\n" , msg1);
 
printf("\n\n");
 
//		exit(0);
	}
 
 
 
}
int main(int argc, char *argv[]) 
{
 
 
 
// 사용 예
//$message = "☆━2008년*♡*┐┃설날부턴 ° ː│。°더많이°│ː 。사랑할께~┃└*♡* *‥─━★";
//$key = "985786";
 
	char msg[2000];
	char key[10];
 
	strcpy(msg , "☆━2008년*♡*┐┃설날부턴 ° ː│。°더많이°│ː 。사랑할께~┃└*♡* *‥─━★");
	strcpy(key , "9857861");
 
	char ret_msg1[2000] = "";
	char ret_msg2[2000] = "";
 
	//printf("msg = /%s/\n" , msg);
 
	encrypt_md5(ret_msg1 , msg , key);
 
	printf("Encrypted = /%s/\n" , ret_msg1);
 
	encrypt_md5(ret_msg2 , ret_msg1 , key);
 
	//printf("Decrypted = /%s/\n" , ret_msg2);
 
 
}

첨부된 이미지는 결과 화면 입니다.

File attachments: 
첨부파일 크기
Image icon Untitled-2.gif29.25 KB
7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

683b0004f295d6...의 MD5 해시 값을 두 글자씩 16진수로 읽어들일텐데, 00은 널 문자라서 그 뒤는 문자열로 인식이 안되나봅니다.
아마도 PHP에서는 널 문자 뒤의 문자도 문자열에 포함하도록 길이를 같이 저장하겠죠.

mrbaen의 이미지

ditto님이 말한데로 그런듯 해요.
cdd23788b34d84cf9006f1b832ea6dee
cd d2 37 88 b3 4d 84 cf 90 06 f1 b8 32 ea 6d ee
이것은 0이 연속으로 두번 나오지만 2개식 자르면 00이 아니구요

다음거(문제되는 해시값)
683b0004f295d63bbc392a08053210fb
68 3b 00 04 f2 95 d6 3b bc 39 2a 08 05 32 10 fb
이거는 문제가 발생 하네요.

해결을 어떻게 해야 할까요?
머리가 오버히팅 되두 한참 되서
해결방법을 못찾겠어요 ㅠ.ㅠ

좀 알려주세요.

bushi의 이미지

의외로 공력이 좀 드는군요.

[bushi@rose net]$ 
[bushi@rose net]$ gcc -s -o cv cv.c md5.c -Wall
[bushi@rose net]$ 
[bushi@rose net]$ ./cv
source len 108
encrypted len 108
decrypted len 108
result: ☆━2008년*♡*┐┃설날부턴 ° ː│。°더많이°│ː 。사랑할께~┃└*♡* *‥─━★
[bushi@rose net]$ 

말씀드릴게 많은데, 어디서부터 시작해야 될 지 몰라 그냥 코드를 첨부합니다.
"문자열" 이라는 개념은 C 에서 좀 애매합니다.
그러니 그냥 바이트의 배열이라 생각하시고, "길이" 를 알아낼 수 있는 별도의 방법을 강구하셔야 합니다.

짧게 요약하자면, null terminate 기준으로 동작하는 모든 C 함수를 회피하셔야 합니다.
strlen(), printf(), sprintf(), strcpy() 등등.

php 코드의 한줄 한줄을 그대로 옮기는 식으로 만든 코드니 방향만 잡으시고 재작성하시는 게 좋습니다.

OTL

댓글 첨부 파일: 
첨부파일 크기
Plain text icon cv.c.txt3.25 KB
select99의 이미지

C 에서 스트링 개념이 애매한게 아니라..

스트링이 아닌곳에 스트링함수를 쓰기때문에 에러나는거지요..

mrbaen의 이미지

죄송한데요 md5.h 랑 md5.c 파일은 어떤거를 가져다가 쓰면 되는거져?
php 소스에 있는거 가져다 썻더니 안되는데
openssl/md5.h 인클루드 하고
php소스에 잇는거랑 gcc소스에 있는거랑 가져다가 해봤는데 에러 몇백줄이 좌악 ㅠ.ㅠ

bushi의 이미지

컴파일하려고 삽질하지 마시고, 방향만 잡은 뒤 재작성하세요.
사용된 md5.[ch] 는 검색하면 쉽게 발견하실 수 있습니다.

cv.c 코드 내에 버그가 있습니다.
crypt_md5() 를 다음처럼 수정해야 합니다.

crypt_md5(...)
{
  ....
  char *msg_o, *msg;
 
  msg_o = msg = strdup(_msg);
  ...
 
  while(...) {
      ...
      /* $buffer=substr($msg,0,16); */
      set_str(&buffer, msg, this_len);
      ....
      /* $msg=substr($msg,16); */
      msg += this_len;
  }
 
  ...
  free(msg_o);
}

아무 생각없이 디버깅하다, 아무 생각없이 집어넣은 memcpy() 때문에.

덧.
C 에서 byte stream 을 어찌할까하는 고민을 해보시려면,
리눅스 커널의 skbuff 가 좋은 참고자료가 된다고 생각합니다.
queue, list, fifo, filo, lifo, lilo 등 모든 환경과 조건에 사용할 수 있습니다.
(네트웍에 관련된 부가설비는 무시하고 보세요.)
커널에 있는 list 설비(라 해봤자 list.h 꼴랑 하나지만)와 더불어 자주 애용하는 으뜸설비.

OTL

bushi의 이미지

아아.. 실패입니다.
memcpy() 로 해결이 되는 줄 알았는데 memcpy() 를 잘 못 사용한 버그였더군요.

수정된 코드를 첨부했습니다만, 보시다시피 encrypt() 와 decrypt() 가 나뉘어져 버렸습니다.
어설픈 string_t 가지고는 안되나봐요.

OTL

댓글 첨부 파일: 
첨부파일 크기
파일 cv.c5.85 KB
keedi의 이미지

위에서 다른분들께서 말씀하신 것처럼 문자열과 바이트 스트림의 차이를 정확하게 인지해야 할겁니다.

간단하게 생각하면,
바이트 스트림 구조체 만들고 바이트 스트림 처리용 함수 몇개 만들고,
문자열 구조체(문자열, 길이) 만들고 문자열 처리용 함수 몇개 만들면,
이런 류의 컨버팅 작업 때 편하게 이용할 수 있을 겁니다.

---------------------------
Smashing Watermelons~!!
Whatever Nevermind~!!

Keedi Kim

----
use perl;

Keedi Kim

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.