STREAM Cipher는 평문 데이터를 한 비트 ( 또는 한 바이트 ) 단위로 암호화하는 대칭키 암호화 방식이다. 여기서 대칭키는 암호화 키와 복호화 키가 같은 것을 의미한다. 일반적으로 암호화 속도가 빠르고 메모리 사용량이 적어, 제한된 자원 환경 (IOT, 무선통신)등에서 많이 사용된다.
[ 평문 비트 ] 11001010
[ 키 스트림 ] 10101100
[ XOR 결과 ] 01100110 → 암호문
스트림 암호는 한 비트/바이트씩 처리하는 빠르고 경량화된 암호 방식
XOR + 키 스트림으로 암호화 수행
RC4, ChaCha20 등 다양한 알고리즘 존재
Nonce/IV를 꼭 다르게 사용해야 보안 유지
먼저 주어지는 문제 파일은 2개이다.

우선 실제 암호화에 사용된 파일이 주어진다. 각 클래스 내의 함수의 역할을 살펴본다.
init : 클래스의 초기화를 담당
num2bits : 인자로 넘어온 seed(=num)의 값의 범위를 검증하고, 2진수로 변경한 뒤 빈자리는 0을 채워 16비트로 만든다.
bits2num : 인자 비트에 0b를 추가한다.
shift : 맨 마지막 비트 1개를 맨 앞으로 옮기고, 옮긴 비트를 전달한다.
getNbits : 옮겨진 비트들을 통해 8비트 스트림을 만든다.
encrypt : getNbits를 통해 8비트 스트림을 생성한 후 0b를 추가하여 2진수 스트림을 만든다. ( 키 스트림 )
그리고 해당 스트림을 평문과 XOR 연산을 하여 암호문을 생성한다.
decrypt : getNbits를 통해 8비트 스트림을 생성한 후 0b를 추가하여 2진수 스트림을 만든다. ( 키 스트림 )
암호문과 키 스트림을 XOR 연산하여 평문을 획득한다.
이제 실제 암호화를 호출하여 사용한 코드를 살펴본다.

flag라는 파일에 대해 seed값을 랜덤으로 뽑아내어 키 스트림을 생성한다. 또한 encrypt된 암호문이 주어진다.
encrypted flag > 3cef03c64ac240c349971d9e4c951cc14ec4199f409249c21e964ac540c540944f901c934cc240934d96419f4b9e4d9f1cc41dc61dc34e9219c31bc11a914f9141c61ada
우리는 이 때 사용된 키 스트림(Seed 값)이 무엇인지 모른다. 이를 알아내는 코드를 작성해야 한다.
가장 먼저 hex값을 다시 바이트 포맷으로 변경하고, 키 스트림을 찾아내야 한다. 키 스트림의 범위는 0 ~ 65535이다.
반복문을 통해 각 키 스트림에 대해 계산하여 복호화 된 메시지에 DH{ 과 } 포맷이 있다면 출력하는 방식으로 코드를 작성하였다.

위는 변경된 코드이다. 이제 실행해보면

seed값은 58654일 때, 해당 flag가 평문으로 존재했던 것을 확인할 수 있다.
Flag = DH{a2e8d10e942df6ca8851ef12b8b8377d44e8451983958dceaed65adcfb6769ab}