Skip to content

한양대학교 전자투표시스템

류형욱 edited this page Aug 16, 2013 · 11 revisions

한양대학교 전자투표시스템(hanyang-voting)

이 문서는 한양대학교 전자투표시스템(hanyang-voting)의 목적, 설계, 책임, 그리고 구현에 대한 내용을 다룹니다.

용어

한양대학교 전자투표시스템은 다양한 목적을 가진 투표 및 선거에 적용할 수 있는 진지한(serious) 투표 시스템입니다. 선거뿐만 아니라 다양한 투표에 사용할 수 있으므로, 시스템 내부 및 프론트엔드에서 사용하는 용어로, "선거" 대신 "투표"만을 사용합니다. 대신에, 투표 제목 및 명칭은 스트링 테이블에 의하여 변경할 수 있도록 합니다.

투표 주체

선거 또는 투표 진행 과정에 다음 주체가 참여합니다:

  • 투표관리본부(headquarters) : 투표 준비 단계 및 투표 진행, 개표, 결과 확정 단계까지 투표를 총괄하며, 특히 중앙 서버를 관리합니다.
  • 투표관리위원회(commission) : 투표관리본부의 시스템 운용과 선거 운영을 감시하고 검증합니다. 또, 투표 진행 도중에 개표를 진행할 수 없도록 개표 복호화 키를 분산하여 보관합니다.
  • 투표소(station) : 대개 각 단과대학에 하나씩 설치되며, 투표소관리인이 배치되어 있고 여러 하위 기표소가 설치됩니다.
  • 기표소(booth) : 투표소에 다수가 설치되며, 투표인이 실제 기표를 수행하는 장소입니다.
  • 투표소관리인 : 각 투표소에서 투표인의 신원을 확인하고, 투표소 머신을 사용하며 투표소 머신과 기표소 머신을 관리합니다. 투표소관리인은 시스템에서 별도로 관리되지 않습니다.
  • 투표인(voter) : 투표소와 기표소에서 투표권을 행사합니다. 투표인은 시스템에서 관리됩니다.

시스템 제한

시스템이 처리할 수 있는 최대 투표 규모는 투표소 50개, 기표소 300개, 투표인 60000명, 투표 진행 시간 6시간으로 합니다.

이번 프로젝트에서 구현하는 투표는 각 질문에 대하여 객관식으로 한 항목에만 기표할 수 있는 투표입니다. 한 투표에서 여러 질문이 주어질 수 있으며, 투표인은 원하는 질문에만 참여할 수 있습니다. 따라서 총학생회 대표, 단과대학 대표, 학과 대표 선거를 동시에 진행할 수 있으며, 원하는 선거에만 참여하고 참여하지 않는 선거에 기권할 수 있습니다.

이 시스템은 진지한 시스템이며, 대규모의 공정한 투표에 사용될 것을 목표로 합니다. 따라서 각 투표를 진행하는 것에 있어서 시스템에 대한 이해가 있는 개발자의 투입을 필요로 할 수도 있습니다.

시스템 구조

  • 주 서버(server-main) : 안전하고 보안이 유지된 장소에서 전체 투표를 총괄하는 서버입니다. MariaDB 내부 데이터베이스 서버 1대, 프론트엔드 서버 1대로 운영됩니다. 프론트엔드 서버 앞에 보안을 위한 Nginx 리버스 프록시 서버가 위치할 수 있습니다.
  • 현황 서버(server-status) : 투표진행본부와 투표관리위원회가 사용하는 입도가 가는 현황 서비스, 그리고 외부에 공개하는 입도가 굵은 현황 서비스로 구성됩니다. Google App Engine에 위치하며, 일정 간격을 두고 주 서버에 현황을 요청하여 캐시된 정보를 제공합니다. 따라서 다량의 트래픽 또는 공격에 대해 상대적으로 안전합니다.
  • 투표소 클라이언트(client-station) : 투표소(station)에 1개 이상(바람직하게는 기표소 머신보다 적을 것)이 설치되며, 하위 기표소를 관리합니다. 개념적으로, 투표소에는 투표소 클라이언트에 의하여 관리되는 다수의 기표소와 기표소 머신이 설치됩니다.
  • 기표소 클라이언트(client-booth) : 기표소(booth)에 예외 없이 1개 설치됩니다.
  • 배포 서버(server-deploy) : 투표소 클라이언트와 기표소 클라이언트에서 실행되는 바이너리를 배포하기 위한 서버입니다. 기본적인 인증만 사용합니다. 정적인 컨텐츠만 제공하는 서버입니다.
  • 키 생성자(key-generator) : 투표값 암호에 사용할 비대칭 키를 생성하는 독립된 도구입니다. 키 생성 도구는 네트워크에 접속되지 않은 상태에서 공개 키를 생성하여 공개 키 USB 메모리 스틱에 저장하고, 공개 키는 시스템의 모든 필요한 주체에게 전파됩니다. 키 생성 도구는 공개 키와 함께 생성된 비밀 키를 비밀 키 USB 메모리 스틱에 2회 이상 단일 또는 분산 저장하고, 즉시 폐기합니다. 단일 저장하는 경우, 동일한 비밀 키가 저장된 3개의 USB 메모리 스틱을 만든 다음 투표 종료까지 봉인하여 보관할 수 있습니다. 분산 저장하는 경우, n개로 분산하고 3회 중복 저장하려고 할 때, 3n개의 USB 메모리 스틱을 만든 다음 선거관리위원에게 분배하고 투표 종료까지 분산 보관할 수 있습니다.

시스템은 주 서버에 모든 정보가 집중되는 구조입니다. 투표소 클라이언트와 기표소 클라이언트는 한양대학교 교내 무선랜 네트워크를 통하여 주 서버와 직접 통신합니다. 정보 전송의 모든 과정은 SSL(https) 전송 계층 보안 위에서 이루어집니다. 또, 투표 당일 오프라인으로 분배되는 키를 사용하는 AES 블록 암호 알고리즘에 의한 메시지 계층 보안을 사용합니다. 따라서 이러한 메커니즘이 완벽하다면, 무선 네트워크를 통한 전송 과정에서 발생할 수 있는 보안 위협에 크게 염려하지 않는 것이 합리적입니다.

투표소 클라이언트와 기표소 클라이언트는 Windows 7, Windows 8 운영체제가 설치된, 카메라가 설치된 개인용 컴퓨터이어야 합니다. Windows 8에서 개발되어, Windows 8과 Windows 7에서 검증될 것입니다. 각 클라이언트는 배포 서버에서 배포되는 투표소 클라이언트 소프트웨어 또는 기표소 클라이언트 소프트웨어를 설치하고 인증 절차를 거쳐 투표 시스템의 일부가 될 수 있습니다. 각 클라이언트 소프트웨어는 처음 입력되는 인증 암호를 투표가 진행되는 동안 메모리가 저장하고 있지만, 인증 정보를 제외한 내용은 클라이언트 머신에 보존되지 않으며, 모든 정보는 주 서버에 의하여 처리되고 주 서버에서 보관됩니다. 즉, 클라이언트는 stateless하다고 볼 수 있습니다. 그러므로 투표 종료 이후 악의를 가진 공격자가 투표소 클라이언트 머신과 기표소 클라이언트 머신을 조사하더라도 의미가 있는 정보를 얻기 힘들 것입니다. 무엇보다도, 클라이언트 머신에 보존되는 정보가 없으므로 불상의 이유로 머신 failure가 발생한 경우, 신속하게 다른 머신으로 대체하여 투표를 계속 진행할 수 있습니다. 이 경우, 대체되는 클라이언트의 인증 암호를 입력하면 마지막에 입력된 클라이언트가 대체하도록 시스템이 디자인될 것입니다.

기존에 논의되었던 USB 메모리 스틱은 사용하지 않고, 투표 시작 전 적절한 시기에 네트워크를 통해 소프트웨어를 다운로드하는 방법을 사용하는 것이 좋겠습니다. 이것이 소프트웨어의 급작스런 변경에 대응할 수 있는 방법이라고 생각됩니다. 단, 투표 시작 전에 클라이언트 머신에 악성 소프트웨어가 없는지 미리 확인해야 합니다.

사용할 기술

  • 주 서버(server-main)는 Spring Framework, MyBatis를 이용하여 개발됩니다. 주 서버는 RESTful 인터페이스를 노출하고 JSON 또는 XML 형식 응답을 제공하는, 일종의 API 서버입니다. 개발자나 투표 총괄자가 아닌 최종 사용자는, 주 서버의 웹 페이지에 브라우저로 직접 접근하는 일이 없습니다. 주 서버는 안전한 데이터 센터 환경에 위치해야 합니다. 또 암호화된 통신을 사용하기 위하여 인증 기관에서 발급한 인증서가 필요합니다.
  • 데이터베이스 서버는 MariaDB를 사용합니다. MariaDB는 MySQL을 개선하였으며 MySQL과 호환되는, 비교적 검증된 공개 DBMS입니다. 데이터베이스 서버는 내부망에 위치하며 주 서버만 접근할 수 있습니다. 데이터베이스 서버는 안전한 데이터 센터 환경에 위치해야 합니다.
  • 현황 서버(server-status)와 배포 서버(server-deploy)는 Google App Engine에서 Python으로 개발되며, Jinja2 템플릿 엔진을 사용합니다. 투표 기간 중 Google App Engine의 무료 할당량(quota)을 초과할 것이 예상되므로, 미리 결제를 활성화하고 비용을 투입해야 합니다.
  • 투표소 클라이언트(client-station)와 기표소 클라이언트(client-booth)는 .NET Framework 4.0, C#, WPF(데이터 바인딩 사용)에서 개발됩니다.

투표 워크플로우

  • 시스템 개발을 완료합니다. 최고!
  • 투표인명부를 확정합니다. 각 투표인의 학번, 단과대학, 학과, 이름, 사진 데이터를 받아 통합 작업을 수행합니다.
  • 투표 목록과 각 투표의 투표값 목록을 확정합니다. 각 투표는 전체 투표인 대상, 특정 단과대학 대상, 특정 학과 대상으로 제한할 수 있습니다. 투표 목록과 각 투표의 투표값 목록은 확정 이후 절대로 변경할 수 없습니다.
  • 키 생성자 도구를 이용하여 공개 키를 얻고 비밀 키를 적절히 처리하여 투표 종료 이전까지 주 서버와 격리합니다. 공개 키는 주 서버에 저장하고, 주 서버가 모든 다른 서버로 전파합니다.
  • 투표를 며칠 남기고 투표권 QR 코드 뭉치를 인쇄합니다. 각 투표권 QR 코드는 여백을 포함하여 한 변의 길이가 8cm 정도인 정사각형 모양이며, 백색 바탕에 검정색으로 QR 코드가 형성되어 있습니다. 투표권 QR 코드 뭉치를 각 투표소로 나눕니다.
  • 투표 당일 새벽에 모든 투표소와 기표소에 대하여 활성화 암호를 생성하여 종이에 인쇄한 후, 투표소 관리인에게 배부합니다. 종이에는 QR 코드가 인쇄되며, QR 코드를 투표소 머신과 기표소 머신에 인식하여 투표소 머신과 각 기표소 머신을 활성화합니다.
  • 투표소 준비 작업을 수행합니다. 투표소 관리인은 받은 투표권 QR 코드 뭉치를 차례로 모두 투표소 머신 카메라에 인식합니다. 그러면 투표소 머신의 스크린에 투표권 QR 코드 뭉치의 소속 그룹이 표시되며, 투표소 관리인은 스크린의 지시에 따라 자신의 투표소에 배정된 투표권 QR 코드 뭉치의 그룹을 분리합니다. 그룹은 3개 이상이 바람직하며, 하나의 그룹은 투표 진행 내내 사용되지 않는 QR 코드 뭉치(허수 투표권)이며, 나머지 그룹은 시간에 따라 사용 그룹이 변경되는 일반 투표권입니다. 자동 변경 또는 총괄자의 명령에 따라 각 투표소는 다른 QR 코드 뭉치 그룹을 변경하여 사용합니다. 모든 QR 코드 인식 시도는 로그로 남기 때문에, 복사나 촬영 등 부정적인 QR 코드 사용을 막을 수 있습니다.
  • 투표를 시작합니다! 투표는 총괄자의 명령에 따른, 클라이언트에 대한 주 서버의 명령에 의해 시작됩니다.
  • 투표인이 들이닥칩니다. 투표인은 투표소의 신원 확인대(투표소 머신)에 줄을 섭니다. 투표소 관리인이 신분증 대조를 통해 신원을 확인하면 학번을 입력하고 데이터베이스의 사진과 한 번 더 대조합니다.
  • 대조가 완료되면 화면에 해당 투표인이 투표할 수 있는 투표의 목록이 나타나며, 마우스 또는 터치스크린, 터치패드를 통해 서명할 수 있게 됩니다. 투표인은 직접 투표하고자 하는 투표에 해당하는 서명란에 서명을 할 수 있습니다. 서명과 투표 또는 기권 여부가 주 서버에 저장됩니다.
  • 참여할 투표를 모두 고른 후, 사용할 수 있는 그룹의 QR 코드 뭉치에서 임의로 하나를 투표인이 직접 고르도록 합니다. 투표인이 고른 QR 코드를 투표소 관리인이 투표소 머신에 인식하면 해당 투표권 QR 코드가 참여할 투표에 대해서만 활성화됩니다.
  • 투표인이 해당 투표소의 아무 기표소에 들어가 직접 고른 투표권 QR 코드를 인식하면, 참여하기로 결정한 각 투표에 대해서 투표할 수 있습니다. 여기에서 기권할 수도 있습니다. 인터페이스는 매표를 방지할 수 있도록 만듭니다. 이를테면, 별도의 확인 버튼 없이 선택지를 선택하는 순간 투표가 완료되며, 어떤 선택지를 선택하였는지는 안내되지 않고 단순히 특정 투표에 대하여 투표가 완료되었다는 사실만 안내합니다.
  • 투표인이 사용한 QR 코드를 반납합니다. QR 코드를 반납하지 않고는 투표장을 벗어날 수 없도록 투표인 동선을 만들어야 합니다. 이때, QR 코드를 다시 적절한 그룹으로 넣어야 하므로, 신원 확인은 수행하지 않고 QR 코드의 그룹 확인만 수행하는 투표소 머신과 담당자를 배치하는 것이 좋을 수도 있습니다. (테스트 투표에서 여러 투표소 유형을 실험해 봅시다.) 물론 모든 투표소 머신은 신원 확인, QR 코드 활성화와 비활성화, QR 코드 그룹 확인을 수행할 수 있습니다. QR 코드 비활성화는 QR 코드 활성화까지 마친 투표인이 기표소가 들어가기 전에 투표권을 포기하는 경우입니다. 이 경우 투표인명부에는 투표를 완료한 것으로 집계되며, 투표 결과에서는 무효표로 집계됩니다.
  • 투표를 종료합니다. 자동 또는 수동으로 투표를 종료할 수 있으며, 투표가 종료되면 새로운 투표를 할 수 없고, 완료하지 않은 이미 진행 중인 투표도 더 이상 진행할 수 없게 됩니다.
  • 개표 전, 봉인 또는 분산 저장되었던 비밀 키를 주 서버에 넣고, 투표값 복호화 작업을 수행합니다.
  • 개표와 함께, QR 코드 사용 빈도나 지나친 QR 코드 사용 실패와 같은 이상을 확인합니다. 개표 결과를 확정하고, 투표인명부와 투표권 QR 코드-투표값-투표 시각 정보를 모든 사람에게 공개합니다.

왜 투표권 QR 코드인가

모든 투표에는 투표 부정 또는 의도하지 않은 투표, 개표 오류의 가능성이 존재합니다. 한편, 전자 투표에는 전통적인 종이 투표 방식에 비하여 정확한 집계와 빠른 개표, 적은 노동력과 같은 많은 장점이 있음에도 불구하고, 악의적인 공격자의 공격이 일어날 경우 전통적인 투표 방식에 비하여 파급력이 더 큽니다. 또, 기존 방식에서 쉽게 드러나지 않고 검증이 불가능하였던 오류가, 전자 투표에서는 검증 가능하게 됨에 따라서, 실제에 비하여 더욱 더 신뢰성이 더 낮은 인상을 주고 있습니다.

우리가 제안하는 투표 방식에서는 투표 종료 이전에 개표 또는 일부 개표가 진행되는 것에 대응하기 위하여, 공개 키와 비밀 키 쌍을 만들고 비밀 키를 투표 종료까지 알 수 없도록 하고, 공개 키로 투표값을 암호화하는 방법을 사용합니다. 적절한 암호화 알고리즘을 사용하면 공개 키로 암호화한 정보를 비밀 키 없이는 복호화하기가 극히 어렵게 만들 수 있으며, 이 방법은 현재 세계적으로 금융 거래와 같은 고도의 보안이 요구되는 분야에 이의 없이 채택되는 강력한 수단입니다.

선거 부정이나 해킹, 의도하지 않은 오류가 발생하였을 경우 여러 관계인의 동의 하에 자세한 로그를 열람하기를 원할 수도 있습니다. 이때 투표인-투표값 쌍을 보관하는 것은 문제의 소지가 될 수 있으므로, 우리가 제안하는 방법은 QR 코드-투표값 쌍을 보관하는 것입니다. 처음 QR 코드 활성화 과정에서 투표인-QR 코드 쌍이 보관되지 않는다는 것을 보증할 수 있다면, QR 코드-투표값 쌍에서는 의미 있는 정보를 뽑아낼 수 없습니다. 만약 각 투표소에 여러 기표소가 존재하고 투표인이 아무 기표소에 줄을 설 수 있다면, 투표인명부에 서명한 시각과 투표를 완료한 시각과의 관계가 섞이고 큰 의미를 가지지 못하므로, 투표인을 특정하기가 어려울 것입니다.

만약 인증을 우회할 수 있는 방법을 악의를 가진 공격자가 발견하여 대량의 투표 패킷을 주 서버로 송신하는 공격이 발생하였다고 합시다. 그렇다면, 특정 QR 코드 또는 적은 수의 QR 코드의 투표수가 매우 높을 것입니다. 또, 자동으로 또는 사람의 명령에 따라서 각 투표소가 사용하는 QR 코드 뭉치 그룹이 수시로 변경되므로, 잘못된 시각에 잘못된 그룹의 QR 코드로 투표하였거나, 잘못된 QR 코드를 인식하여 실패하는 경우의 수가 매우 높을 것입니다. 따라서 특정 QR 코드가 유출되는 경우에도(유출되더라도 비활성화되어 있다면 투표할 수 없으므로 더 안전하겠지만) 해당 QR 코드를 간단히 배제할 수 있으므로 전체 시스템으로 부정이 확산되지 않습니다.

투표권 QR 코드에는 QR 코드뿐만 아니라 사람이 읽을 수 있는 간단한 정보도 포함됩니다. 이를테면, "한양대학교 공과대학 제2투표소 제42투표권"과 같은 식입니다. 투표인은 자신이 사용한 투표권의 고유한 번호와 투표를 마친 시각을 기억합니다. 개표 과정이 끝난 이후, 현황 서버에는 모든 투표인의 투표 완료 여부와 참여한 투표의 목록, 서명이 공개됩니다. 또, 모든 QR 코드-투표값-투표 완료 시각 쌍이 모든 사람에게 공개됩니다. 각 투표인은 투표 시각과 투표권 고유 번호, 투표값을 보고 집계 여부를 확인할 수 있습니다. 투표 시각-사용한 투표권 고유 번호-투표인을 정확히 매칭하는 것은 불가능하며, 매표도 불가능합니다. 게다가 기표소 내에서의 사진 촬영은 금지되어 있으므로 투표인을 특정하는 것은 더 어렵습니다.

QR코드-투표값 쌍이 공개되면, 각 투표인에게 다른 사람의 투표 정보는 큰 쓸모가 없지만, 자신의 투표 정보가 정확히 집계되었는지는 알 수 있습니다. 따라서 우리가 제안하는 이 투표 시스템은 공공에 의하여 검증을 받는 투표 시스템입니다.

비대칭 암호화 알고리즘

투표값의 크기는 기껏해야 수십 개로 매우 작기 때문에, RSA 비대칭 암호화 알고리즘과 같은, 동일한 평문과 키를 사용할 때 항상 동일한 암호문이 나오는 암호화 알고리즘을 주 암호화 알고리즘으로 사용할 경우 보안 문제가 발생할 수 있는 여지가 있다. 따라서 동일한 평문과 키를 사용하는 경우에도 적절한 난수 생성 알고리즘에 의하여 평문에 대하여 두 배의 길이를 갖는 항상 다른 암호문을 생성하는 ElGamal 암호화 알고리즘을 사용한다.

C#과 Java의 기본 라이브러리에서 ElGamal에 대한 구현을 제공하지 않으므로 외부 라이브러리를 사용하거나 직접 구현한다. 암호화 알고리즘을 직접 구현하는 것은 많은 위험 부담이 있지만, 알고리즘이 간단하므로 현재는 직접 구현한 암호화 루틴을 적용한다.

참고 문헌

  • 김동균, 김은정, 공개키 암호학과 전자투표, 2003, 청문각
  • 이윤호, 이광우, 박상준, 김승주, 원동호, 향상된 사용자 편의성을 갖는 안전한 전자 투표 영수증 발급 방식, 제2회 암호학술논문 공모 수상논문집, 2006, 국가정보원
  • 김재선, 21세기 전자정부와 전자투표제도, 2011, 오름