Възпроизводими компилации: доказване че софтуерът, който работи, е софтуерът, който инспектирахте
Швейцария публикува своя избирателен изходен код, за да го инспектира всеки — и изследователи веднага открили скрита задна врата, която можеше да фалшифицира перфектно изглеждащо доказателство, докато тихо променяше гласовете.
Е март 2019 г. и в Берн, Швейцарската пощта прави нещо, което звучи като еталона на избирателната прозрачност. Нейната интернет избирателна система — изградена с испанския доставчик Scytl, предназначена за използване при задължителни швейцарски федерални гласувания — е готова да има публикуван онлайн цял си изходен код за света да чете.
Това е това, което защитниците на демокрацията настояваха години. Отворете черния кутия. Позволете на експерти да видят. Доверие чрез инспекция.
Преди няколко седмици, три независими криптографа — Sarah Jamie Lewis, Olivier Pereira и Vanessa Teague — провериха. И това, което откриха, не беше успокояващо.
Ловушката, която никой не видя, докато някой не погледна
Центърът на системата беше математическо доказателство. След като всички гласове бяха смесени и разбъркани, за да се запази анонимността, софтуерът щеше да генерира криптографско "доказателство за разбъркване" — математика, която теоретично демонстрира на всеки, който проверява, че разбърканието е извършено правилно и никакви гласове не са променени.
Наричаше се универсална проверяемост. Идеята: не трябва да доверявате сървъра. Проверявате доказателството сами.
Изследователите открили, че доказателството е построено върху нещо, наречено схема на задна врата на ангажирани стойности. На прост английски: доказателството за разбъркване можеше да бъде направено да "верифицира" правилно дори ако гласовете са тихо променени — при условие, че знаете стойността на задната врата. И стойността на задната врата беше притежавана от операторите на системата.
С други думи, орган, който знаеше тази стойност, можеше да генерира транскрипт на доказателството за разбъркване, който преминаваше верификация, докато пренаредеше всеки един бюлетин. Твърдението за "универсална проверяемост" беше неопровержимо отвън.
Назваха своя документ "Ceci n'est pas une preuve." Това не е доказателство.
Швейцарската пощта и Scytl признаха откритието. Швейцарските органи спряха системата.
Урокът звучи техничен. Не е. Недостатъкът беше невидим, докато кодът беше затворен. Стана намираем в момента, в който беше отворен. Но намирането му все още изисква световни криптографи, работещи седмици. По-широкият въпрос — този, на който всъщност е посвещена тази публикация — е: какво се случва между "някой може да чете кода" и "можете да сте сигурни, че кодът, който беше прочетен, е това, което работеше на машината"?
Швейцарският случай разтвори кода. Но разкри по-дълбока пропаст, която дори отворен код не затваря автоматично.
Четенето на рецептата не е същото като опитване на ястието
Представете си ресторант, който публикува своите рецепти. Всеки ингредиент, всяка техника, всяка стъпка — всичко онлайн, всичко време.
Сега представете си, че кухнята е заключена. Можете да прочетете какво е трябвало да се случи. Не можете да видите какво действително се случва.
Това е точно ситуацията при повечето избирателни софтуер, дори при софтуер с отворен код. Публикуването на изходен код е необходимо условие за независима проверка. Не е достатъчно.
Ето защо. Софтуерът, който прочитате в хранилище, не е софтуерът, който работи на машината. Между "изходен код" и "работеща програма" има верига от стъпки:
- Компилър взема кода и го превежда в четлив за машина бинарен код.
- Бинарният код се пакетира, инсталира на избирателен хардуер или сървъри и криптографски запечатва — или не.
- В момента на избирателния ден машина се стартира и работи това, което е на нея.
Всяка от тези стъпки е място, където работещия код може да се различава от кода, който инспектирахте, без видимо доказателство. Компилър може да бъде манипулиран да вмъкне код, който не се появява в изходния код. Бинарният код може да бъде сменен след като е построен. Машина може да стартира различна версия от тази, която мислихте, че беше заредена.
Швейцарската задна врата живееше в кода. Но различна задна врата можеше да живее навсякъде в тази верига — и никога да не се появи в кода вообще.
Проблемът с възпроизводимите компилации, на прост език
Има дисциплина в софтуерното инженерство, наречена възпроизводими компилации. Нейната цел е проста: имайки един и същ изходен код, един и същ компилър и един и същи инструкции за компилиране, всеки, който пуска процеса на компилиране, трябва да получи идентичен бинарен код — байт за байт, бит за бит — всеки път.
Това е важно, защото ви дава начин да проверите. Ако органът по избори публикува хеш на бинарния код — уникален цифров отпечатък на софтуера на машината — и ако можете независимо да възпроизведете точно този същ бинарен код от публикувания изходен код, имате криптографско гарантиране, че кодът на машината е кодът, който прочетохте.
Ако бинарният код не се совпада, знаете, че нещо се е променило между кода и машината. Не знаете какво се е променило. Но знаете да попитате.
Без възпроизводими компилации, пропастта между "инспектиран код" и "работещ софтуер" е невидима. Нямате инструмент да я проверите. Сте обратно на доверяването на органа, който направи компилирането.
Проектът Reproducible Builds — кръстосан избор на софтуерното инженерство — документира систематично колко сложно е да се постигне това и колко различни начини верига за компилиране има, за да произведе различни резултати от идентичен изходен код. Компилърите вграждат времеви печати. Свързващите устройства вмъкват променливи на окръжението. Редът на файлове варира. Всеки е механизъм, чрез който две "идентични" компилирания могат да произведат различни бинарни кодове без някой да намерява измама.
Удостоверяване: втората половина на проблема
Дори ако вашето компилиране е възпроизводимо, втори проблем остава. Възпроизводимостта доказва, че някой може да възпроизведе същия бинарен код от кода. Не доказва, че бинарният код, работещ сега на вашата избирателна машина, е този бинарен код.
Тук идва удостоверяванието.
Удостоверяванието е процес на криптографско подписване на твърдение: "Това устройство работи софтуерния бинарен код X, построен в момент T, с хеш H." Подписът трябва да идва от нещо, устойчиво на манипулиране — в идеалния случай от хардуер, който не може да бъде отменен от софтуер след стартиране, като например Trusted Platform Module (TPM) или модул на хардуерна сигурност. Подписаното твърдение може тогава да бъде проверено от всеки, който има публичния ключ.
Мислете на това като на печат, устойчив на манипулиране на карта памет — с изключение, че вместо физически стикер, който се скъсва при отваряне, това е математичен подпис, който можете да проверите без доверяването на лицето, което ви предава картата.
Заедно, възпроизводимите компилации и удостоверяванието образуват верига: четете кода → го компилирате и получавате бинарен код H → проверявате че работещото устройство удостоверява бинарния код H → сте сигурни че машината работи кода, който прочетохте.
Без тази верига имате две несвързани факта: тук е изходния код и тук е машина, която работи нещо. Дали тези две неща се съответстват е въпрос на доверие, не на проверка.
"Ние работим със сертифициран софтуер с отворен код" е твърдение. Възпроизводимите компилации и удостоверяванието са това, което го прави проверяемо.
Какво швейцарският случай ни казва за по-дълбокия проблем
Върнете се в Швейцария. Изследователите открили задната врата, защото прочетоха кода. Швейцарската пощта признаде недостатъка и спря системата. До сега: системата работи както е предвидено.
Но забележете какво не бе проверено в никоя докладана версия на тази история. Дори ако задната врата не съществуваше в кода, никоя независима страна нямаше механизъм да потвърди, че бинарният код, работещ на сървърите на Швейцарската пощта, беше компилиран от този точен изходен код — и не от леко модифицирана версия с недостатък, който никога не се появи в публичния код.
Това не е хипотетично. През 2003 г. компютърният учен Ken Thompson, в неговата лекция за наградата Turing, описа как компилър може да бъде модифициран да вмъкне задна врата в програма автоматично — и тогава по-нататък модифициран да вмъкне задната врата в себе си, така че дори компилирането на самия компилър от чист изходен код щеше да произведе компрометиран бинарен код. Кодът изглежда чист. Компилърът изглежда чист. Резултатът е троянизиран.
Това не е екзотичен теоретичен атак. Това е добре разбран клас на заплаха. И защита срещу него е възпроизводими компилации: ако резултатът е детерминиран и публикуван, всяка независима страна може да преконструира от кода и да открие несъответствие. Ако не е — ако всяко компилиране произведе различен бинарен код за невинни технически причини — сравнението никога не може да бъде направено.
Швейцарският случай доказа, че отворен код е по-добър от затворен код. Той също доказа, че отворен код, сам по себе си, не е достатъчен.
Пропастта, която нашия проследяващ пропасти наблюдава
При TrustVoting проследяваме специфична пропаст: отсъствието, в повечето внедрени избирателни системи, на публично проверени възпроизводими компилации и удостоверяване на устройството. Можете да видите колко често се появява тази пропаст и къде, по целия свят.
Швейцарската система имаше отворен код. Това е един от най-прозрачните интернет избирателни програми в демократичния свят. Изследователи все още откриха недостатък в криптографията — което би было неоткриваемо в затворена система. И дори след като този недостатък беше открит и коригиран, независимо наблюдател нямаше механизъм да потвърди, че коригиран бинарния код на сървъра беше произведен от коригирания изходен код.
Това е пропастта. Тя се намира точно в шева между кода, който можете да прочетете, и софтуера, който всъщност обработва вашия глас.
Няколко неща, които щяха да я затворят:
- Публично публикувани инструкции за компилиране, които произвеждат точния бинарен хеш, който органът твърди, че работи — така че всеки достатъчно технически наблюдател може независимо да проверя.
- Подписано удостоверяване от устройство, устойчиво на манипулиране, на всяка избирателна машина, публикуващо хеша на работещия бинарния код заедно с всеки резултатен пакет.
- Непрекъснато, след внедряване наблюдение срещу публикувания хеш — така че софтуерна смяна, която се случи след сертификация, но преди избирателния ден, щеше да е открита.
Нито една от тези не е екзотична. Те са стандартна практика в внедрене на софтуер с висока сигурност. Те в голямата си част отсъстват от требованията за сертификация на избирателни системи.
Какво все още не можете да проверите днес — и какво щяха да го поправи
Ето неудобната позиция, в която сме останали след Швейцария 2019.
Знаем, че отворен код е по-добър. Задната врата беше открита точно защото кодът беше четлив. Затворена система щеше да доставя недостатъка необнаружен.
Знаем, че криптографската проверяемост е по-добра от писмените следи сами. Философията на цялата швейцарска система — универсална проверяемост, математически проверяеми доказателства — е опит да позволи на гласоподавателите да потвърдят, без доверяване на органа, че техния глас беше броен.
И знаем, че и двете са недостатъчни, ако не включват моста между код и работещ бинарни код.
Точно сега, за практически всяка избирателна система внедрена по света, честният отговор на "как知 знам, че софтуерът на тази машина е софтуерът, който беше преглеждан?" е: не можете. Доверявате органа, който го внедри.
Това доверие може да е добре поставено. Но доверието не е проверка. Германския федерален конституционен съд разбра това, когато решено през 2009 г., че електронното гласуване е само законно, когато обикновени граждане — не само експерти — могат независимо да проверят всяка съществена стъпка от бюлетин до резултат. Разуждението на съда се отнася толкова остро до софтуерното внедряне, както до броенето на гласове: ако потвърждаването, че правилния код работи, изисква доверяване на хората, които го пускат, съществената стъпка на проверка липсва.
Поправката не е да се разрушат усилията за отворен код за избори. Това е да се завършат. Отворен код плюс възпроизводими компилации плюс подписано удостоверяване плюс публично публикувани бинарни хешове равнява система, където "софтуерът, който инспектирахте, е софтуерът, който работеше" е проверяемо от всеки с лаптоп и любопитство — не само от органа, който го внедри.
Докато тази верига не бъде затворена, всяко "ние използваме отворен, сертифициран софтуер" твърдение е покана да доверявате. И избирателна система, която ви моли да я доверите вместо да ви показва доказателството, не е завършила решаването на проблема.
Прочетете 2-минутната версия на тази аргументация
Изследвайте глобалната карта на пропастите при проверка на избирателна технология
Източници
- Lewis, Pereira, Teague — Ceci n'est pas une preuve (trapdoor commitments in the Scytl-SwissPost Internet voting system), 2019
- Bundesverfassungsgericht, Judgment of 3 March 2009, 2 BvC 3/07 and 2 BvC 4/07 (English translation)
- Springall, Finkbeiner, Durumeric, Kitcat, Hursti, MacAlpine, Halderman — Security Analysis of the Estonian Internet Voting System, ACM CCS 2014
- California Secretary of State news release (Aug. 21, 2018): certifying LA County VSAP Tally as California's first certified open-source election technology
- Halderman, Teague — The New South Wales iVote System: Security Failures and Verification Flaws in a Live Online Election, E-Vote-ID 2015 (arXiv:1504.05646)
- Curling v. Raffensperger, No. 1:17-cv-2989-AT, Opinion and Order (N.D. Ga. Oct. 11, 2020), Doc. 964 (Justia)