Цифровий паспорт товару не показує всім одне й те саме. Покупець бачить загальнодоступні дані. Ремонтна майстерня або підприємство з переробки бачить більше. Орган ринкового нагляду бачить усе. Це вже з’ясовано, і європейські стандарти тепер чітко це закріплюють.
Цікаве питання звучить дещо тихіше: якщо комусь, крім загальнодоступних даних, відкриваються захищені поля, чи може він підтвердити, що саме ці поля є справжніми? Чи йому доведеться покладатися на те, що платформа правильно їх відібрала та передала без змін?
Для більшості платформ чесна відповідь така: довіра. Ми побудували нашу платформу так, щоб відповіддю було «доказ» - не лише для публічних полів, а й для кожного поля, яке додається лише під час розкриття. Чому ця різниця має значення і чому ми обрали для цього більш складний шлях.
Усі однаково дотримуються правил доступу
EN 18239, європейський стандарт щодо прав доступу, безпеки та конфіденційності в DPP, вимагає контролю доступу для кожного елемента даних: для кожного поля існує правило, хто має право його переглядати. Це правильна вимога, і її неважко виконати. Який статус мають ці стандарти, ми детально роз’яснили у статті Гармонізовані стандарти.
Звичайний спосіб реалізації - фільтрування на стороні сервера. Сервер знає, хто надсилає запит, перевіряє, що ця особа має право бачити, і повертає саме цей фрагмент. Контроль доступу: виконано. Більше стандарт не вимагає.
Є одна проблема, про яку стандарт не дбає: Фрагмент надходить без підпису. Читач отримує підібраний спеціально для нього вигляд і мусить вірити, що сервер чесно здійснив вибір і нічого не змінив під час передачі. Для публічної інформаційної брошури це нормально. Але для значення, на якому переробник одразу базує ціну вживаної батареї, це занадто велика довіра.
Де одиночний підпис досягає своїх меж
Очевидним рішенням є підписання даних. Для обох кінців шкали добре працює звичайний підпис: підписати публічний вигляд, підписати повний набір даних, і обидва перевіряються за допомогою відкритого ключа без втручання сервера. Як це відбувається детально, описано в статті «Підписи та сертифікати в DPP».
Проблема виникає посередині. Підпис на весь документ охоплює саме той набір полів, який був присутній під час підписання. Якщо авторизованому читачеві додатково відкрити захищене поле, це поле виходить за межі підписаного набору і надходить до нього без захисту. Якщо ж замість цього з самого початку підписати повний набір даних, підпис охоплюватиме все, але тоді доведеться показувати все кожному.
Таким чином, проміжні ланки випадають із системи: ремонтна майстерня, страховик, переробник. Якби ми хотіли заздалегідь підписати кожну можливу комбінацію «хто що бачить», то для кожної комбінації знадобився б окремий підписаний документ, а кількість комбінацій стрімко зростає з кожною новою групою доступу. Ніхто цього не робить. Доводиться повертатися до непідписаного серверного фільтра, і проміжна ланка знову базується на довірі.
Підписувати кожне поле окремо
Існує краща конструкція, і саме на ній ми будуємо нашу платформу. Замість того, щоб підписувати готовий документ як єдиний блок, видавець за один цикл підписання окремо визначає кожне поле (для тих, хто знається на стандартах: сертифікат W3C ecdsa-sd-2023 для вибіркового розкриття).
Кожен вигляд починається з публічного ядра
Кожен вигляд починається з одних і тих самих публічних полів. Те, що читач бачить понад це, додається поле за полем, і кожне з цих полів продовжує вести до публічного ключа видавця - в автономному режимі, без повторного підписання та без довіри до організації, яка сформувала цей вигляд. Поля, на які немає права, просто відсутні. Не замазані, а взагалі відсутні, і про них нічого не просочується.
Чому «непорушність» - це суть справи
Уявіть собі нотаріуса, який засвідчує не лист у цілому, а кожен абзац окремо. Публічний лист отримує кожен. Хто має право на більше, отримує додаткові абзаци, і кожен із них продовжує мати печатку того самого нотаріуса. За звичайної процедури платформа вилучає ці абзаци для вас, і те, що до вас надходить, містить лише її слово.
Чому саме «непорушеність» має значення, варто пояснити ще одним реченням. Цілісна печатка не означає, що зміст є правдивим. Вона означає: саме це написав видавець, і з того часу ніхто не змінив у ньому жодного знака. Таким чином, з кола довіри виключається кожен, хто лише передавав документ далі - проміжний носій, мережа, архів, ми. Хто саме передав вам паспорт, вже не має значення.
А печатка є бінарною. Вона або ціла, або ні - напівзламаної печатки не існує. Якщо вона зламана, ви не дізнаєтеся, який саме рядок було змінено, а лише те, що ви більше не можете довіряти всьому аркушу. Тому немає поступової різниці в тому, чи додаткові поля надходять до вас із печаткою, чи без неї: без печатки вони не є дещо менш підтвердженими - вони взагалі не підтверджені.
Обидва способи перегляду
Кожен може перевірити це самостійно. Transpareo Time Machine - це наш відкритий додаток для перегляду паспортів продукції: він переглядає історію версій паспорта й при цьому перевіряє кожну підпис у браузері користувача, не звертаючись до нашого сервера. У ній публічно доступні два зразки паспортів. Паспорт футболки містить підпис, що охоплює весь документ, а паспорт батареї - розкриття інформації по полях.
Обидві специфікації є відкритими стандартами W3C: eddsa-jcs-2022 для підпису, що охоплює весь документ, та ecdsa-sd-2023 для розкриття інформації за полями. Впровадити їх може кожен, хто бажає. Саме через складність реалізації багато хто цього не робитиме: підпис на весь документ значно дешевше створити та підтримувати, і тим, хто надає лише публічні дані, цього цілком достатньо.
Те, що Time Machine підтримує обидва методи, є навмисним і так і залишиться. Вона не належить жодній платформі. Перевіряючий, який приймає лише дорожчий метод, був би інструментом для нас і ні для кого іншого.
Кому розкриваються захищені поля
Варто запитати, кому взагалі розкривається щось, крім публічних даних. Не випадковій покупниці - вона отримує публічний паспорт. Це переробник, який оцінює вартість вживаного акумуляторного блоку; страховик, який визначає вартість ризику; рециклер, який сортує хімічні речовини; державний орган, який розслідує справу. Саме ці особи є тими, чиї рішення залежать від грошей або безпеки.
І саме ці поля зазвичай залишаються нерозкритими. Той, хто мав би найбільше підстав вимагати криптографічного підтвердження, не отримує його саме для тих полів, від яких залежить його рішення.
Ми вважаємо, що знак перевірки повинен означати одне й те саме для всіх. Напис «Перевірено Transpareo» на розширеному огляді ремонтної майстерні означає те саме, що й на публічному паспорті покупця: кожна показана сфера походить від емітента і з того часу не змінювалася. Печатка, яка ставиться лише на публічні поля, - це лише половина печатки.
Більше, ніж вимагає стандарт
Скажемо відверто: нічого з цього не є обов’язковим. ## СтандартEN 18239 вимагає, щоб доступ контролювався, і серверний фільтр бездоганно контролює доступ. Також забезпечення можливості криптографічної перевірки відкритих полів - це те, що ми робимо додатково, а не просто галочка, якої від нас вимагає норматив.
Саме тому про це варто написати. Було б легко дотриматися букви стандарту, надати серверний фільтр і оголосити цей етап завершеним. Нам же важливіше, щоб ця обіцянка діяла скрізь, де з’являється печатка. Адже весь сенс підписаного паспорта полягає в тому, що ніхто не мусить довіряти платформі. Виключення середнього рівня як винятку повертає саме ту довіру, яку підпис мав би усунути.
Той самий принцип дозволяє забути про певне поле
Визначення кожного поля окремо має ще одну особливість, і саме її вимагає європейське законодавство. Загальний регламент про захист даних надає людям право вимагати видалення персональних даних. Набір даних, підписаний як єдиний блок, не може виконати цю вимогу без руйнування власного підпису.
Оскільки тут кожне поле є самостійним, окреме поле можна видалити, а решта даних залишається перевіреною. Якщо персональні дані випадково потрапляють у паспорт, їх можна повністю видалити, і паспорт залишається дійсним: не потрібно видавати новий документ, не порушується історія використання. Поля, які згідно з законодавством підлягають збереженню, залишаються на місці; те, що можна видалити, видаляється на запит, навіть через роки.
Проте це цілком звичайний паспорт
Ніщо з цього не робить паспорт особливим об’єктом, який можуть відкрити лише наші інструменти. Він залишається верифікованим посвідченням у форматі JSON-LD - форматі, до якого рухається світ веб-стандартів, і тому самому форматі, який використовують Протокол прозорості ООН та решта середовища W3C.
Отже, паспорт, який покупниця сканує у браузері, є тим самим об’єктом, який може зчитати партнер у кімнаті даних, і його може перевірити будь-який перевіряючий, що дотримується стандартів, а не лише наш. Додаткова безпека нічого не коштує читачеві й нікого не прив’язує до нас.
Чому це технічно складно
По-перше, щоб не виникло хибного враження: ми не винайшли цей метод. ecdsa-sd-2023 - це публічна специфікація W3C, криптографія, що лежить в її основі, не є нашою розробкою, і той, хто хоче її реалізувати, може ознайомитися з нею. Складно не те, щоб придумати ідею. Складно реалізувати її так, щоб пароль працював ще й через десять років. Саме в цьому полягає робота, і про це можна сказати дещо корисне.
Різниця здається незначною, але вона змінює саму основу: звичайний підпис обчислюється на основі байтів документа. Селективне розкриття інформації обчислюється на основі його тверджень. Перед підписанням паспорт приводиться до стандартизованої форми, в якій кожна інформація представлена як окреме, самостійне речення. Лише завдяки цьому можна опустити одне речення, не пошкодивши решту.
Тим самим виникає проблема, якої немає у байтовій підписі: та сама стандартизована форма має точно відтворитися через десять років. Не приблизно, а символ за символом, інакше підтвердження вже не підійде. Цьому заважають три речі, і всі три є непомітними.
Числа втрачають свій тип. Якщо записати число просто у форматі JSON, то на шляху втрачається інформація про те, яким саме числом воно було. Таке значення, як 2.0, після проходження через JSON повертається як 2. Для людини це те саме, для стандартизованої форми - інше речення, і перевірка завершується невдачею.
Назви ще не означають змісту. Щоб утворилася стандартизована форма, кожне ім’я поля має розшифровуватися як однозначне значення. Якщо одне з них відсутнє, поле під час перетворення непомітно зникає. Воно тоді залишається в паспорті, але підтвердження його не охоплює, і ніхто цього не помічає.
Значення зазвичай знаходяться в мережі. Це зіставлення міститься у словниках, які більшість інструментів завантажують через мережу під час перевірки. Хто так робить, той ставить перевірюваність свого паспорта в залежність від того, чи чужа адреса ще через десять років дасть відповідь, причому без змін.
Як ми це вирішили
Ми усунули ці три проблеми на корені, замість того щоб виправляти їх пізніше.
Типи. Кожне значення записується разом із його типом, і публікація припиняється, щойно у стандартизованій формі з’являється хоча б одне число без типу. Таким чином, помилка виявляється там, де вона коштує лише один рядок, а не через роки у вигляді незрозумілого порушення перевірки.
Словники. Кожен словник, на який посилається паспорт, зберігається у нас локально і ніколи не завантажується через мережу. Невідома адреса - це жорстке переривання під час підписання, а не тихе повернення до порожнього результату.
Ідентифікатори. Кожен вузол у документі має стабільний ідентифікатор, щоб стандартизована форма залишалася відтворюваною, замість того, щоб при кожному прогоні присвоювати нові допоміжні імена.
Найскладніша частина полягає в принципі «Bring Your Own Key» (принеси свій власний ключ). Для кожного випуску потрібен додатковий короткочасний ключ, за допомогою якого окремо підписуються поля, що підлягають оприлюдненню. Цей ключ генерує та знищує сам видавець. Якби він зберігався у нас, ми могли б згодом вигадати окремі поля, і незалежність підпису експонента залишалася б лише на словах. Ми перевіряємо отримане підтвердження за допомогою збереженого відкритого ключа, перш ніж довіряти йому.
Кожен паспорт містить два таких підтвердження: одне від експонента та одне від Transpareo, і кожне з них генерується незалежно для перегляду читачем. Два підписи, два незалежні один від одного авторитети - навіть для одного окремого оприлюдненого поля.
На наш погляд, ці зусилля доцільні. Ми не додавали можливість перевірки вже після створення; платформа була розроблена з урахуванням цього ще з першої версії. Кожен паспорт підписується під час публікації та прив’язується до попередньої версії. Незмінний десятирічний архів створено і починає діяти, щойно паспорти зареєстровані в реєстрі EU-DPP. Підписування кожного поля замість цілого блоку є розширенням цього ядра, а не накладенням на те, що ніколи не було для цього призначене.
На якому етапі ми перебуваємо
Якщо звести все до суті, вибір простий. Ви можете оприлюднити захищені поля й попросити читача довіритися вашому фільтру - це відповідає стандарту. Або ви можете оприлюднити їх і одразу надати доказ - це відповідає вищим вимогам, на які, на нашу думку, ці поля заслуговують.
Ми вирішили надавати доказ для кожного читача, адже печатка має означати одне й те саме незалежно від того, хто на неї дивиться. Для тих, хто хоче побачити, як це працює: обидві демо-версії, посилання на які наведено вище, перевіряються безпосередньо в браузері, в автономному режимі, лише за допомогою відкритого ключа.
