RC4 stream암호화 키생성까지 구현
CS/암호학 2016. 2. 17. 04:56
간단한 스트림 암호화인 RC4를 구현해봤다. 지금은 잘 사용되지 않는 암호화 방식이라 아쉽지만... 암호학 복습을 하면서 설계가 적힌 spec문서를 발견해서 한번 만들어봤다.
크게 5바이트 seed를 사용해서 0~255까지 정렬된 S배열과 같은 범위를 seed값으 연속으로 채운 K배열을 연산하고 섞어서 S배열을 만드는 Schedule 함수와 그렇게 만든 값을 다시 섞고 연산해서 K배열로 집어넣는 Generator 함수가 있다.
최종적으로 생성되는 keystream이 바로 이 K배열이고 스트림 암호는 평문에 이 keystream을 xor 연산하여 암호문을 얻어낸다.
암복호화까지는 만들지 않고 테스트벡터와 비교하기 위해 keystream만 64바이트까지 뽑도록 만들었다.
#include<stdio.h> void Schedul(int *seed, int *key, int *s){ int i, j = 0; int tmp; for (i = 0; i < 256; i++){ s[i] = i; key[i] = seed[i % 5]; } for (i = 0; i < 256; i++){ j = (j + s[i] + key[i]) % 256; tmp = s[i]; s[i] = s[j]; s[j] = tmp; } } void Generater(int *key, int *s){ int i = 0, j = 0; int c, tmp; for (c = 0; c < 256; c++){ i = (i + 1) % 256; j = (j + s[i]) % 256; tmp = s[i]; s[i] = s[j]; s[j] = tmp; key[i] = s[(s[i] + s[j]) % 256]; } } void Print_key(int *k){ int i; for (i = 1; i < 64; i++){ printf("%x ", k[i]); } } main(){ int s[256]; int k[256]; int seed[5]; int i; printf("input(seed 4byte): "); for (i = 0; i < 5; i++){ scanf("%x", &seed[i]); } Schedul(&seed, &k, &s); Generater(&k, &s); Print_key(k); }
코드는 위와 같다. 내 부족한 실력으로 만들었는데도 코드가 상당히 간결하다. 이정도 간결한 알고리즘으로 그래도 나름 튼튼한 암호를 만들어내다니 처음 생각해낸 사람이 존경스럽다.
테스트 벡터와 비교해보면
이렇게 0x0102030405 시드값에 대하여 같은 키스트림을 뽑아내는 것을 확인할 수 있다.