XOR 비트연산 할 때 0이 나오면 멈춥니다

l595659의 이미지

소켓 통신 시 XOR 비트 연산으로 데이터를 암호화하려고 합니다

예를 들어 키가 "encrypt"이고 데이터가 "connect"인 경우 t는 0이 되고 데이터는 올바르게 암호화 및 해독되지 않습니다. 또한 데이터값과 키값이 중간에 같으면 0이 되어 기능을 그대로 종료합니다.
(data:connection, key:encrypt -> recv data는 connect만 있음)

암호화 코드를 어떻게 받아야하나요?? 아니면 recv나 send할때 버퍼 크기도 같이 보내서 그만큼 반복을 시켜야 할까요..?

char Encryption(char strEncordeData[])
{
	memset(m_socket_comm.encrypt, 0, BUF_SIZE);
 
	m_socket_comm.keycount = 0;
	int length = strlen(strEncordeData);
	for (int i = 0; i < length; i++)
	{
		m_socket_comm.encrypt[i] = strEncordeData[i] ^ m_socket_comm.key[m_socket_comm.keycount];
		if (m_socket_comm.keycount == strlen(m_socket_comm.key))
		{
			m_socket_comm.keycount = 0;
		}
		m_socket_comm.keycount++;
	}
	return *strEncordeData;
}
라스코니의 이미지

1. strEncordeData 의 내용을 어디에서도 업데이트하고 있지 않음.
2. int length = strlen(strEncordeData); 에서 length가 뭐가 찍히는가요?
3. encrypt 의 type이 궁금함
4. strlen(m_socket_comm.key)의 값을 알고 싶음

l595659의 이미지

1. strEncordeData 가 받는 변수

void TCPServer::ServSend()
{
	for (int i = 0; i < m_socket_comm.client_list.size(); i++)
	{
		Encryption(readbuffer);
		send(m_socket_comm.client_list[i], readbuffer, strlen(readbuffer), 0);
	}
}

이렇게 send/recv할때 버퍼값을 넣어주는 식으로 사용하고있습니다

2. int length = strlen(strEncordeData); 는 버퍼의 길이때문에 넣어놨습니다.
3. encrypt는 char encrypt[1024] 입니다.
4. strlen(m_socket_comm.key)는 10입니다.
char key[BUFSIZE] = "connection"

라스코니의 이미지

2) length가 어떤 값인지 궁금합니다.

그리고
Encryption(readbuffer);
send(m_socket_comm.client_list[i], readbuffer, strlen(readbuffer), 0);
에서 readbuffer의 변경이 일어나지 않기 때문에 send는 암호화전 값을 보냅니다. 암호화된 값을 보내기 위해서는 m_socket_comm.encrypt[] 값을 가져올 수가 있어야 합니다.

l595659의 이미지

length 값이 strlen(strEncordeData)으로 되어있어서 send/recv 할 때 데이터에 따라서 길이가 달라지다보니...
일단 send/recv 한 버퍼의 길이 값 입니다. connect라면 7로 되구요

send(m_socket_comm.client_list[i], readbuffer, strlen(readbuffer), 0);
에선 return 으로 strEncordeData로 받아오기 때문에 암호화된 데이터 가져오지 않나요?? 지금까지 잘 가져오는것 같길래요..

라스코니의 이미지

Encryption() 함수에서 strEncordeData[]에 대한 어떤 변경도 안합니다.
암호화하기 전에는 상관없었지만 암호화한 후 값을 가져와야 되지 않나요?

l595659의 이미지

아 그러네요 제가 이것저것 계속 만지다가 그 부분이 누락된것 같습니다

원래는 m_socket_comm.encrypt[i] = strEncordeData[i]도 있었는데 깜빡했나봐요 죄송합니다..

l595659의 이미지

여러 방법으로 시도해봤는데 결국 하나씩 문제가 생기네요
예를 들어서 key[i]와 strEncordeData[i] 와 같을 때 keycount를 0으로 보내는걸로 해봤었는데
이때는 복호화 때 문제가 생기더라구요..

라스코니의 이미지

이런 동작을 원하시는건가요?

#include <stdio.h>
#include <string.h>
 
char key[100] = "key1";
 
void En_Decryption(char strEncordeData[], int strLen)
{
	int keycount = 0;
	for (int i = 0; i < strLen; i++)
	{
		strEncordeData[i] = strEncordeData[i] ^ key[keycount];
		if (keycount == strlen(key))
		{
			keycount = 0;
		}
		keycount++;
	}
}
 
int main()
{
    int i;
    char text[100] = "Hello,World!";
    int text_length = strlen(text);
 
    printf("text length : %d\n", text_length);
 
    printf("original  : %s\n", text);
    printf("original  : ");
    for(i=0; i<text_length; i++)
        printf("%02x ", text[i]);
    printf("\n");
 
 
    En_Decryption(text, text_length);
    printf("encrypted : ");
    for(i=0; i<text_length; i++)
        printf("%02x ", text[i]);
    printf("\n");
 
 
    En_Decryption(text, text_length);
    printf("decrypted : %s\n", text);
    printf("decrypted : ");
    for(i=0; i<text_length; i++)
        printf("%02x ", text[i]);
    printf("\n");
 
    return 0;
}

XOR에 의한 암호화는 사실 복호화도 동일합니다. 제가 짠 코드를 보시고 현재 코드와 무엇이 다른지 체크해 보세요.

Anti-Lock의 이미지

키카운트를 증가시킨뒤 키길이와 비교해야 합니다.

라스코니의 이미지

맞습니다. 아래처럼 바꿔서 해보세요.

		keycount++;
                if (keycount == strlen(key))
		{
			keycount = 0;
		}

l595659의 이미지

올려주신 코드와 같이 매개변수로 strLen을 통신으로 받으려면 send나 recv를 두번해야 하죠??
버퍼길의 정보와 내용을 받아야 할 것 같은데
원래는 한번만 send/recv 한 것을 받아서 암복화 하려고했는데 XOR연산으론 그부분은 힘든가보네요

라스코니의 이미지

암호화된 데이터 길이를 strlen() 함수로 확인하면 안됩니다. 암호화된 데이터에 0 (null) 값이 있을수도 있기 때문이죠.

recv()에서 되돌려주는 "받은 데이터 길이"를 가지고 넘겨주면 됩니다.

l595659의 이미지

받거나 보낼 데이터 각각해서 두번 보내는데 클라이언트 측에서 recv도 2번 하느라 여기서 꼬이네요..

void TCPClnt::ClntRecv()
{
	memset(buf, 0, BUF_SIZE);
 
	int i = 0;
	recv_size = 0;
	if (recv_size == 0)
	{
		recv_size = recv(m_socket_comm.clnt_sock, buf, BUF_SIZE, 0);
	}
	else if (recv_size != SOCKET_ERROR)
	{
		recv(m_socket_comm.clnt_sock, m_socket_comm.cDatasize, 1, 0);
		m_socket_comm.datasize = m_socket_comm.cDatasize[0];
 
		Decryption(buf, m_socket_comm.datasize);
		for (i = 0; i > strlen(buf); i++)
		{
			RecvBuf[i] = buf[i];
		}
	}
 
}
l595659의 이미지

else if때문에 꼬였네요!

라스코니의 이미지

두번 받는 식으로 문제를 해결하시면 안됩니다.

l595659의 이미지

지금은 recv나 send에 define한 bufsize 만큼 보내라고 되어있어서 일단 저렇게 했습니다
시간 날때 다시 수정하려구요!

l595659의 이미지

만약에 키 값이 : KEY 이고 버퍼값이 KEY 이면 recv() 할 땐 0으로 받아와서 데이터 길이도 0이 되는 부분때문에 저번에 2개로 받아서 했었는데 이런경우엔 recv()에서 받은 데이터 길이를 가지고 넘겨줄 수 없지 않나요?
recv함수에서 버퍼사이즈 넣는건 최대 받을 데이터 길이로 알고있어서요

라스코니의 이미지

recv() 함수의 return 값이 바로 읽은 데이터 길이입니다.
recv() 함수의 man page를 읽어 보세요.

l595659의 이미지

키와 같은 값을 암호화 하면 0'0' 그니까 NULL 값이 가지 않습니까?

서버에서 send를 할 때 암호화해서 보내기 때문에 NULL 값을 recv 하니 return 도 0이 나옵니다.

recv나 send를 두번한 이유가 기존 데이터의 길이와 암호화된 데이터를 주고받아서 NULL 값이 나와도 제대로 암호화/복호화 하라는 의도였거든요

라스코니의 이미지

AAAAA ^ AAAAA = 00000 이 나옵니다. 길이가 0이 아니라 5 그대로죠.
보낼때 strlen of 00000 하면 길이가 0으로 계산되기 때문에 보내지지가 않겠죠. 그래서 암호화(XOR)한 값을 strlen()으로 길이를 가져오면 안됩니다. 다르게 관리해야 하겠죠.

send(00000) 하면 그대로 상대방이 recv()로 00000로 받습니다. 그리고 그 return 값이 5가 되죠.

l595659의 이미지

buf를 배열로 그냥 크게 잡고 memset으로 전부 0으로 초기화 해서 쓰다보니까 그런건지..

현재 BUF_SIZE 를 1024로 놓고 buf도 buf[BUF_SIZE]로 한 뒤에
 recv_size = recv(m_socket_comm.clnt_sock, buf, BUF_SIZE, 0);
위와같이 받으면 recv_size가 결국 1024가 되더라구요..

라스코니의 이미지

보내는 쪽에서 send(length = 1024)로 보냈기 때문에 recv()에서 그렇게 받은 겁니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.