XOR을 연산 시 같은 비트라면 0을 다르면 1을 반환한다.
예를 들어 0x41 (0b01000001) XOR 0x42 (0b01000010)를 수행 시 0x03 (0b0011)이 반환된다.
그렇기 때문에 XOR
연산 시 키
와 입력 값의 길이
가 같아
야 한다.
예시로 파일의 데이터를 읽은 후 XOR 암호화해본다.
데이터를 읽어보자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *key = "xor test key";
int keylen = strlen(key);
long rlen = 0;
FILE *rfp, *wfp = NULL;
char *rdata, *wdata = NULL;
rfp = fopen("test1.txt", "rb");
if (rfp == NULL) return 0;
fseek(rfp, 0, SEEK_END);
rlen = ftell(rfp);
rewind(rfp);
rdata = (char*)malloc(sizeof(char) * rlen);
if (rdata == NULL) {
fclose(rfp);
return 0;
}
if (fread(rdata, 1, rlen, rfp) != rlen) {
free(rdata);
fclose(rfp);
return 0;
}
fclose(rfp);
...
}
암호화한 데이터를 저장할 기반을 마련하자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
...
wfp = fopen("test1.enc", "wb");
if (wfp == NULL) {
free(rdata);
return 0;
}
wdata = (char*)malloc(sizeof(char) * rlen);
if (wdata == NULL) {
free(rdata);
fclose(wfp);
return 0;
}
...
}
보통 프로그래밍 언어에서 XOR 연산자는 ^
이고 길이를 맞추어 XOR 연산을 하자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
...
for (int i = 0; i < rlen; i++) wdata[i] = rdata[i] ^ key[i % keylen];
rewind(wfp);
fwrite(wdata, 1, rlen, wfp);
fclose(wfp);
free(rdata);
free(wdata);
return 0;
}
전체 코드는 다음과 같다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *key = "xor test key";
int keylen = strlen(key);
long rlen = 0;
FILE *rfp, *wfp = NULL;
char *rdata, *wdata = NULL;
rfp = fopen("test1.txt", "rb");
if (rfp == NULL) return 0;
fseek(rfp, 0, SEEK_END);
rlen = ftell(rfp);
rewind(rfp);
rdata = (char*)malloc(sizeof(char) * rlen);
if (rdata == NULL) {
fclose(rfp);
return 0;
}
if (fread(rdata, 1, rlen, rfp) != rlen) {
free(rdata);
fclose(rfp);
return 0;
}
fclose(rfp);
wfp = fopen("test1.enc", "wb");
if (wfp == NULL) {
free(rdata);
return 0;
}
wdata = (char*)malloc(sizeof(char) * rlen);
if (wdata == NULL) {
free(rdata);
fclose(wfp);
return 0;
}
for (int i = 0; i < rlen; i++) wdata[i] = rdata[i] ^ key[i % keylen];
rewind(wfp);
fwrite(wdata, 1, rlen, wfp);
fclose(wfp);
free(rdata);
free(wdata);
return 0;
}
XOR은 암호화 시 사용했던 키
를 이용하여 다시 한번 암호화를 진행하면 복호화
가 된다.
즉, a XOR b XOR b = a 이다.
같은 비트를 XOR 연산 시 0이 반환되므로 b XOR b는 0이고, a XOR 0은 a이기 때문이다.
예시로 파일의 데이터를 읽은 후 XOR 복호화해본다.
데이터를 읽어보자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *key = "xor test key";
int keylen = strlen(key);
long rlen = 0;
FILE *rfp, *wfp = NULL;
char *rdata, *wdata = NULL;
rfp = fopen("test1.enc", "rb");
if (rfp == NULL) return 0;
fseek(rfp, 0, SEEK_END);
rlen = ftell(rfp);
rewind(rfp);
rdata = (char*)malloc(sizeof(char) * rlen);
if (rdata == NULL) {
fclose(rfp);
return 0;
}
if (fread(rdata, 1, rlen, rfp) != rlen) {
free(rdata);
fclose(rfp);
return 0;
}
fclose(rfp);
...
}
암호화한 데이터를 저장할 기반을 마련하자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
...
wfp = fopen("test2.txt", "wb");
if (wfp == NULL) {
free(rdata);
return 0;
}
wdata = (char*)malloc(sizeof(char) * rlen);
if (wdata == NULL) {
free(rdata);
fclose(wfp);
return 0;
}
...
}
보통 프로그래밍 언어에서 XOR 연산자는 ^
이고 길이를 맞추어 XOR 연산을 하자.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
...
for (int i = 0; i < rlen; i++) wdata[i] = rdata[i] ^ key[i % keylen];
rewind(wfp);
fwrite(wdata, 1, rlen, wfp);
fclose(wfp);
free(rdata);
free(wdata);
return 0;
}
전체 코드는 다음과 같다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *key = "xor test key";
int keylen = strlen(key);
long rlen = 0;
FILE *rfp, *wfp = NULL;
char *rdata, *wdata = NULL;
rfp = fopen("test1.enc", "rb");
if (rfp == NULL) return 0;
fseek(rfp, 0, SEEK_END);
rlen = ftell(rfp);
rewind(rfp);
rdata = (char*)malloc(sizeof(char) * rlen);
if (rdata == NULL) {
fclose(rfp);
return 0;
}
if (fread(rdata, 1, rlen, rfp) != rlen) {
free(rdata);
fclose(rfp);
return 0;
}
fclose(rfp);
wfp = fopen("test2.txt", "wb");
if (wfp == NULL) {
free(rdata);
return 0;
}
wdata = (char*)malloc(sizeof(char) * rlen);
if (wdata == NULL) {
free(rdata);
fclose(wfp);
return 0;
}
for (int i = 0; i < rlen; i++) wdata[i] = rdata[i] ^ key[i % keylen];
rewind(wfp);
fwrite(wdata, 1, rlen, wfp);
fclose(wfp);
free(rdata);
free(wdata);
return 0;
}