Утечки персональных данных в России бьют все рекорды. За два года их совокупное число выросло – только вдумайтесь – в 40 раз. В 2021-м году таких инцидентов было всего четыре, в 2022 – свыше 140, а за первые семь месяцев 2023 года – уже 150.

Одним из возможных путей утечки является передача персональных данных на обработку третьей стороне. По сути, компания передает изображения удостоверяющих документов (паспортов или любых других) своих клиентов незнакомым людям, а что дальше происходит с данными – неизвестно.

Между тем, есть еще один способ ввода данных из документов – прямо на устройстве, без необходимости отправлять куда-то картинку. Он полностью исключает риск любой утечки. Речь идет о нашем мобильном SDK для распознавания паспорта. О том, как мы внедрили наш SDK в PWA (progressive web app), читайте под катом.

Источник: https://t.me/banksta/38477
Источник: https://t.me/banksta/38477

Прогрессивные веб приложения - технология, позволяющая сайту в браузере вашего смартфона стать похожим на нативное приложение. Иметь иконку на экране смартфона после установки, иметь сравнимую отзывчивость интерфейса, хранить кэш и “тяжёлые” с точки зрения скорости загрузки с сервера ресурсы прямо на клиентском устройстве и за счёт этого работать в офлайне, иметь доступ к железу и его вычислительным мощностям. Особым преимуществом PWA является избавление от необходимости размещаться в сторах приложений: если Android позволяет скачивать apk файл из любого источника, то в случае с iOS установить приложение можно только из официального стора, а PWA позволяют не заморачиваться с этим.

Вместе с популярностью PWA каждый год растёт и улучшается поддержка браузерами технологии WebAssembly.  WebAssembly позволяет использовать движок браузера для выполнения тяжелых с точки  зрения вычислений задач, в том числе по анализу изображений. Мы давно занимаемся развитием наших продуктов в этом направлении, благодаря WASM мы успешно распознаем баркоды, банковские карты, документы, счета, номера телефонов внутри браузера клиентского устройства. Работа с WASM позволяет вывести PWA на новый уровень.

PWA - это набор технических практик, среди которых нас сильнее всего интересует возможность кешировать ресурсы страницы: если размер модулей для распознавания баркодов, номеров телефонов и банковских карт позволяет (при хорошем качестве интернет-соединения) быстро загрузить их с сервера, то модули, позволяющие распознавать документы, удостоверяющие личность, лучше хранить на устройстве. Вот, например, сравнение модулей с разной функциональностью:

  • банковские карты и баркоды: 3.5mb gzip

  • Паспорт РФ, карты и баркоды: 8.3 gzip

Как видите, кеширование WASM-модуля вместе с остальными ресурсами позволяет обойтись без необходимости каждый раз загружать ~8Мб с сервера. Механизм PWA, позволяющий кешировать ресурсы, называется Service Worker. Когда ваш сайт запрашивает ресурсы с сервера даже при отсутствии интернета, Service Worker перехватывает запрос и решает что с ним делать: вернуть ресурс из кеша, запросить по API обновление, вывести сообщение и прочее. Этого достаточно, чтобы ваше приложение могло работать быстрее привычного сайта (если ресурсы возвращаются из локального кеша) и было полностью или частично автономно.

Давайте рассмотрим демо-пример для распознавания паспорта РФ, в котором мы поместим в локальный кэш клиентского браузера весь сайт вместе с WASM файлами, так, чтобы они теперь загружались из локального кеша всегда. Это позволит работать приложению полностью оффлайн. Наш демо сайт состоит из:

  • index.html - разметка страницы.

  • app.js - входной скрипт веб страницы. Работа с камерой, передача потока изображений с камеры, отображение результата.

  • worker.js - веб-воркер. Скрипт, принимающий поток изображений с камеры и работающий с WASM объектом.

  • sw.js - сервис-воркер. Скрипт самого сервис воркера.

  • moduleName.js - маленький скрипт, определяющий название WASM сборки для текущего браузера.

В главном скрипте веб страницы производим регистрацию сервисного воркера:

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("sw.js").then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(Service worker registration failed: ${error});
    }
  );
} else {
  console.error("Service workers are not supported.");
}

В сам сервис воркер мы передаем массив адресов, предназначенных для кэширования. Для удобства чтения поделим массивы адресов по группам. Сначала мы добавим сам путь к файлу главной веб-страницы, основной скрипт  и веб-воркер ( именно это веб-воркер, обслуживающий  WASM ). 

// Files to cache
const cacheName = 'smartenginesWasm';
const appShellHtml = [
  'sample.html',
  'app.js',
  'worker.js',
];

Потом опишем массив графических ресурсов веб-страницы. Пусть это будут иконки.

const appShellIcons = [
  'assets/icons/icon-48x48.png',
  'assets/icons/icon-72x72.png',
  'assets/icons/icon-96x96.png',
];

А для кэширования WASM файлов нужно сделать небольшое отступление. WASM в принципе поддерживается сейчас почти в любом браузере, однако существует набор оптимизаций, по-разному поддерживаемый современными (в первую очередь мобильными) браузерами (мы писали об этом тут). Поэтому наши WASM модули делятся на три группы, каждая из которых подгружается в зависимости от технологических возможностей браузера. Для их определения через importScripts() мы подключаем крохотный файл, который возвращает нам имя сборки, подходящей для кэширования для текущей среды исполнения:

importScripts('./moduleName.js');

const module =  await getModuleName();

const WasmUrls = {
  'nosimd.nothreads': [
    'bin/nosimd.nothreads/idengine_wasm.js',
    'bin/nosimd.nothreads/idengine_wasm.wasm'
  ],
  'simd.nothreads': [
    'bin/simd.nothreads/idengine_wasm.js',
    'bin/simd.nothreads/idengine_wasm.wasm'
  ],
  'simd.threads': [
    'bin/simd.threads/idengine_wasm.js',
    'bin/simd.threads/idengine_wasm.wasm',
    'bin/simd.threads/idengine_wasm.worker.js'
  ],
};

Далее мы собираем все адреса в единую кучку, и на событии, когда сервисный воркер готов, подсовываем ее ему:

const all = appShellHtml.concat(appShellIcons).concat(WasmUrls[module])

const cacheName = 'smartenginesWasm';

// Installing Service Worker

self.addEventListener('install', (e) => {
  console.log('[Service Worker] Install');
  e.waitUntil((async () => {
    const cache = await caches.open(cacheName);
    console.log('[Service Worker] Caching all: app shell and content');
    await cache.addAll(all);
  })());
});

Последним шагом является добавление события на прослушивание сетевых запросов.Если браузер начинает что-то запрашивать из сети, сервисный воркер сможет управлять этим:

// Fetching content using Service Worker

self.addEventListener('fetch', (e) => {
  e.respondWith((async () => {
    const r = await caches.match(e.request);
    console.log([Service Worker] Fetching resource: ${e.request.url});
                
    if (r) return r;
  
    const response = await fetch(e.request);
    const cache = await caches.open(cacheName);
    console.log([Service Worker] Caching new resource: ${e.request.url});
    cache.put(e.request, response.clone());
    return response;
  })());
});
})()

Теперь же, после первой загрузки веб страницы для ее последующей работы сетевое соединение больше не требуется. Работу подобного PWA-приложения мы продемонстрируем на видео. 

Заключение

Распознавание документов прямо на устройстве, без необходимости куда-то отправлять картинку, имеет ряд неоспоримых преимуществ - всегда доступно, нет необходимости отправлять изображения с персональными данными пользователя на сторонние сервисы, результат распознавания всегда “полнее” и работа с ним гибче, есть возможность поднять качество распознавания, комбинируя результаты распознавания нескольких кадров. К тому же, с развитием различных фреймворков внедрение библиотеки распознавания становится всё проще - эта статья, иллюстрирующая внедрение в PWA, хороший тому пример.

В целом, современные PWA приложения могут во многом заменить классические приложения для мобильных телефонов в случаях когда приложению необходимо соединение с интернетом (допустим, это банковское приложение - вот свежее исследование на Forbes на эту тему). С развитием поддержки WebAssembly PWA будут получать всё больший функционал, всё сильнее приближаясь по удобству к нативным приложениям, позволяя обеспечить клиентам с разными мобильными ОС одинаковый пользовательский опыт и не уступающую обычным приложениям функциональность.

Комментарии (11)


  1. Uint32
    04.09.2023 10:39
    +1

    способ ввода данных из документов – прямо на устройстве, без необходимости отправлять куда-то картинку

    Вы молодцы! Единственно правильный подход, имхо


    1. SmartEngines Автор
      04.09.2023 10:39
      +1

      Спасибо!


  1. w0lf
    04.09.2023 10:39

    Эээххх, если б это ещё стоило хоть сколь нибудь вменяемых денег...


    1. SmartEngines Автор
      04.09.2023 10:39

      Чем мех лучше, тем он дороже. А чем мех дороже, тем он что? Правильно! Тем он ЛУЧШЕ!

      (с) Девушка с характером, 1939 г.


      1. w0lf
        04.09.2023 10:39
        +3

        Да я даже не о том, чтобы цену уменьшить. Тому бизнесу, кому нужны стандартные пакеты в 5-10 тысяч распознаваний в месяц, наверное цена будет приемлимой. А тем, кому нужно несколько сотен в месяц, что делать?


  1. shasoftX
    04.09.2023 10:39

    Я тут на днях распознавал паспорт в приложении банка чтобы данные паспорта обновить. Десяток попыток и всё мимо. Вроде рамочками обводит все нужные ключевые области, но по итогу не распознаёт.

    Так и пришлось фотки слать :(


    1. SmartEngines Автор
      04.09.2023 10:39
      +1

      Спасибо, а напишите, если возможно, нам в личном сообщении приложением какого банка Вы пользовались. Проверим у них интеграцию.

      Кстати, а в нашем демо-приложении у Вас получается распознать документ? Скачать его на свой телефон можно тут:

      iOS: https://apps.apple.com/us/app/smart-engines/id1593408182

      Android: https://play.google.com/store/apps/details?id=com.smartengines.se


  1. spidersarecute
    04.09.2023 10:39
    +5

    Между тем, есть еще один способ ввода данных из документов – прямо на устройстве, без необходимости отправлять куда-то картинку. Он полностью исключает риск любой утечки.

    Нет. Данные паспорта ведь дальше остаются в возможно дырявом приложении и передаются на сервер, где они опять же, не защищены.

    Чтобы данные были защищены, нужно прекратить их собирать по любому поводу в максимальном объеме. Там, где это требует закон (банк, билеты на поезд, на метро) вместо сканирования паспорта сотрудник просто должен визуально сверять данные покупателя с предъявленным паспортом.

    Ни при каких обстоятельствах человек не должен фотографировать паспорт телефоном.

    Но капиталисты, естественно, не хотят сделать безопаснее, а хотят собрать побольше данных. Находятся даже люди, которые ради дисконтной карты в магазине дают паспорт.


    1. Alexufo
      04.09.2023 10:39

      сфотографировать - получить изображение документа в энергонезависимую память (сохранить на диск или облако) Для распознавания документа он нужен только в энергозависимой памяти, оперативке, которая находится в изолированном окружении и не так уж долго. Приложения и браузер для этого вполне годятся.
      Есть ситуации, когда сверять глазами - это самое узкое место, или нужны все данные, например, в договор.


  1. asarkhipov
    04.09.2023 10:39
    +1

    А насколько это полезно - распознавать паспорт на клиенте? Кто запретит просто подделать результат сканирования? Это же просто замена форме ввода паспортных данных, и утечки персональных данных тут не при чем - просто если оператор хранит фото паспорта - утечет фото, а если хранит ФИО, серию и номер - утекут они. Вообще давно нужно что-то не настолько чувствительное как паспорт, но способное идентифицировать человека, чтоб можно было безболезненно давать это продавцам билетов и транспортным компаниям, а уж как это читать - все равно, хоть фото, хоть nfc, хоть ручной ввод


    1. SmartEngines Автор
      04.09.2023 10:39
      +1

      Паспорт просят не просто так, а для целей удостоверения личности. И здесь скорее прав комментатор выше, который призывает прекратить проверять личность без необходимого на то повода.