Хабрахабр

DPKI: устраняем недостатки централизованной PKI при помощи блокчейна

Впрочем, не является секретом и то, что главный недостаток это технологии — безусловное доверие к центрам, выпускающим цифровые сертификаты. Ни для кого не секрет, что один из общераспространенных вспомогательных инструментов, без которого невозможна защита данных в открытых сетях, — это технология цифровых сертификатов. Но обо всем по порядку.
Если вы знакомы с принципами работы существующей инфраструктуры общедоступных ключей и знаете ее ключевые недостатки, то можете сразу перейти ниже к описанию того, что мы предлагаем изменить. Директор по технологиям и инновациям компании ENCRY Андрей Чмора предложил новый подход к организации инфраструктуры общедоступных ключей (Public Key Infrastructure, PKI), который поможет устранить существующие в настоящее время недостатки и который использует технологию распределенного реестра (блокчейна).

Что такое цифровые подписи и сертификаты?

Взаимодействие в Интернете всегда подразумевает передачу данных. Все мы заинтересованы в том, чтобы данные передавались безопасным образом. Но что такое безопасность? Наиболее востребованные услуги безопасности — это конфиденциальность, целостность и подлинность. Для этого в настоящее время применяются методы асимметричной криптографии, или криптографии с общедоступным ключом.

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

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

Для решения этой задачи был создан другой механизм. Как достигается целостность и подлинность передаваемой информации? Результат такого хеширования называется «дайджестом», а его зашифрование производится на секретном ключе абонента-отправителя (“заверителя”). Открытые данные не шифруются, но вместе с ним передается результат применения криптографической хеш-функции — «сжатый» образ входной последовательности данных — в зашифрованном виде. Она вместе с открытым текстом передается абоненту-получателю (“проверяющему”). В результате зашифрования дайджеста получается цифровая подпись. Если они совпадают, то это свидетельствует о том, что данные были переданы в подлинном и целостном виде именно абонентом-отправителем, а не видоизменены злоумышленником. Тот расшифровывает цифровую подпись на открытом ключе заверителя и сравнивает с результатом применения криптографической хеш-функции, который проверяющий вычисляет самостоятельно на основе принятых открытых данных.

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

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

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

Откуда берутся цифровые сертификаты?

За выпуск и обслуживание цифровых сертификатов отвечают доверенные центры сертификации, или Удостоверяющие центры (УЦ). Заявитель запрашивает выпуск сертификата в УЦ, проходит идентификацию в Центре регистрации (ЦР) и получает сертификат в УЦ. УЦ гарантирует, что общедоступный ключ из сертификата принадлежит именно тому субъекту, для которого он был выпущен.

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

Один из самых распространенных цифровых сертификатов — это SSL-сертификаты для защищенного режима взаимодействия по протоколу HTTPS. Цифровые сертификаты используется везде, где есть асимметричная криптография. Основная доля приходится на пять-десять крупных доверенных центров: IdenTrust, Comodo, GoDaddy, GlobalSign, DigiCert, CERTUM, Actalis, Secom, Trustwave. Эмиссией SSL-сертификатов занимаются сотни компаний, зарегистрированных в различных юрисдикциях.

УЦ и ЦР — это компоненты PKI, в которую также входят:

  • Открытый справочник – общедоступная база данных, обеспечивающая надежное хранение цифровых сертификатов.
  • Список отозванных сертификатов – общедоступная база данных, обеспечивающая надежное хранение цифровых сертификатов аннулированных общедоступных ключей (например, по причине компрометации парного секретного ключа). Субъекты инфраструктуры могут самостоятельно обращаться к этой базе данных, а могут воспользоваться специализированным протоколом Online Certificate Status Protocol (OCSP), который упрощает процесс проверки.
  • Пользователи сертификатов – обслуживаемые субъекты PKI, заключившие с УЦ соглашение пользователя и осуществляющие проверку цифровой подписи и/или зашифрование данных на основе общедоступного ключа из сертификата.
  • Подписчики – обслуживаемые субъекты PKI, владеющие секретным ключом, парным общедоступному ключу из сертификата, и заключившие с УЦ соглашение подписчика. Подписчик может быть одновременно пользователем сертификата.

Таким образом, доверенные субъекты инфраструктуры общедоступных ключей, к которым относятся УЦ, ЦР и открытые справочники, отвечают за:

Проверку подлинности личности заявителя.
2. 1. Выпуск сертификата общедоступного ключа для заявителя, подлинность личности которого достоверно подтверждена.
4. Профилирование сертификата общедоступного ключа.
3. Предоставление информации о текущем статусе сертификата общедоступного ключа.
Изменение статуса сертификата общедоступного ключа.
5.

Недостатки PKI, какие они?

Фундаментальный недостаток PKI — это наличие доверенных субъектов.
Пользователи должны безусловно доверять УЦ и ЦР. Но, как показывает практика, безусловное доверие чревато серьезными последствиями.

За последние десять лет в этой области произошло несколько крупных скандалов, связанных с уязвимостью инфраструктуры.

— в 2010 году в сети стал распространяться вредонос Stuxnet, который был подписан с использованием украденных цифровых сертификатов от RealTek и JMicron.

На тот момент Symantec был одним из самых крупных УЦ по объемам выпуска. — в 2017 году компания Google обвинила Symantec в выдаче большого числа фальсифицированных сертификатов. В браузере Google Chrome 70 была прекращена поддержка сертификатов, эмитированных этой компаний и аффилированными с ней центрами GeoTrust и Thawte до 1 декабря 2017 года.

Доверие к инфраструктуре было подорвано. УЦ были скомпрометированы, в результате пострадали все — и сами УЦ, а также пользователи и подписчики. Именно этого опасались несколько лет назад в администрации российского президента, где в 2016 году обсуждали возможность создания государственного удостоверяющего центра, который бы выдавал сайтам в рунете SSL-сертификаты. Помимо этого, цифровые сертификаты могут быть заблокированы в условиях политических конфликтов, что также скажется на работе множества ресурсов. Текущее положение дел таково, что даже государственные порталы в России используют цифровые сертификаты, выданные американскими компаниями Comodo или Thawte («дочка» Symantec).

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

Заметим, что полноценного решения этой проблемы не существует в силу теоретико-информационных причин: не располагая достоверной информацией априори, невозможно подтвердить или опровергнуть подлинность того или иного субъекта. Проблема фальсификации учетных данных с целью имперсонификации относится к разряду фундаментальных. Существует множество различных методик проверки, но ни одна из них не предоставляет полноценной гарантии достоверности документов. Как правило, для проверки необходимо предъявить набор документов, удостоверяющих личность заявителя. Соответственно, подлинность личности заявителя тоже не может быть гарантированно подтверждена.

Как можно устранить эти недостатки?

Если проблемы PKI в ее нынешнем положении можно объяснить централизацией, то логично предположить, что децентрализация помогла бы частично устранить обозначенные недостатки.

Откажемся от концепции цифрового сертификата и воспользуемся распределенным реестром для хранения информации об общедоступных ключах. Децентрализация не предполагает наличия доверенных субъектов — если создать децентрализованную инфраструктуру общедоступных ключей (Decentralized Public Key Infrastructure, DPKI), то не нужны ни УЦ, ни ЦР. Вместо цифрового сертификата введем понятие “нотификата”. Реестром в нашем случае мы называем линейную базу данных, состоящую из отдельных записей (блоков), связанных по технологии блокчейн.

Как в предлагаемой DPKI будет выглядеть процесс получения, проверки и аннулирования нотификатов:

Каждый заявитель отправляет заявку на получение нотификата самостоятельно через заполнение формы в ходе регистрации, после чего формирует транзакцию, которая сохраняется в специализированном пуле. 1.

Информация об общедоступном ключе вместе с реквизитами владельца и другими метаданными хранится в распределенном реестре, а не в цифровом сертификате, за эмиссию которого в централизованной PKI отвечает УЦ. 2.

Проверка подлинности личности заявителя выполняется постфактум совместными усилиями сообщества пользователей DPKI, а не ЦР. 3.

Изменить статус общедоступного ключа может только владелец такого нотификата. 4.

Каждый может получить доступ к распределенному реестру и проверить текущий статус общедоступного ключа. 5.

Но надо помнить, что в настоящее время все пользователи цифровых услуг непременно оставляют цифровой след, и этот процесс только продолжит набирать силу. Примечание: на первый взгляд проверка подлинности личности заявителя сообществом может показаться слишком ненадежной. Они уже успешно применяются в ходе расследований как журналистами, так и правоохранительными органами. Открытые электронные реестры юрлиц, карты, оцифровка изображений местности, соцсети — все это общедоступные инструменты. Например, достаточно вспомнить расследования Bellingcat или совместной следственной группы JIT, занимающейся изучением обстоятельств крушения малайзийского Boeing.

Итак, как на практике будет работать децентрализованная инфраструктура общедоступных ключей? Остановимся на описании самой технологии, которую мы запатентовали в 2018 году и по праву считаем своим ноу-хау.

Как в отсутствии УЦ понять, что все ключи принадлежат именно этому владельцу? Представьте, есть некоторый владелец, которому принадлежит множество общедоступных ключей, где каждый ключ — это некая транзакция, которая хранится в реестре. Нулевая транзакция — это своеобразный “якорь”, к которому будут прикрепляться следующие транзакции с данными об общедоступных ключах. Чтобы решить эту задачу, создается нулевая транзакция, в которой содержится информация о владельце и его кошельке (с которого списывается комиссия за размещение транзакции в реестре). Каждая такая транзакция содержит специализированную структуру данных, или по-другому — нотификат.

Нотификат – структурированный набор данных, состоящий из функциональных полей и включающий информацию об общедоступном ключе владельца, персистентность которого гарантируется размещением в одной из связанных записей распределенного реестра.

Нулевая транзакция — как и последующие — представляет собой агрегацию шести полей данных. Следующий логичный вопрос — как формируется нулевая транзакция? Эта пара ключей появляется в тот момент, когда пользователь регистрирует свой кошелек, с которого будет списываться комиссия за размещение в реестре нулевой транзакции и — впоследствии — операции с нотификатами. В ходе формирования нулевой транзакции задействована ключевая пара кошелька (общедоступный и парный секретный ключи).

Здесь RIPEMD160 отвечает за компактное представление данных, разрядность которых не превышает 160 бит. Как показано на рисунке, дайджест общедоступного ключа кошелька формируется путем последовательного применения хеш-функций SHA256 и RIPEMD160. Сам общедоступный ключ заносится в пятое поле. Это важно — ведь реестр не дешевая база данных. У нулевой транзакции это поле ничего не содержит, что отличает ее от последующих транзакций. В первом поле содержатся данные, которые устанавливают связь с предыдущей транзакцией. Для краткости будем называть данные первого и второго полей “связкой” и “проверкой” соответственно. Второе поле — это данные для проверки связности транзакций. Содержимое этих полей формируется методом итеративного хеширования так, как это продемонстрировано на примере связывания второй и третьей транзакций на рисунке ниже.

Данные из первых пяти полей заверяются ЭЦП, которая формируется при помощи секретного ключа кошелька.

Теперь к ней можно “подвязывать” следующие транзакции. Всё, нулевая транзакция отправляется в пул и после успешной проверки заносится в реестр. Рассмотрим, как происходит формирование транзакций, отличных от нулевой.

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

Этот ключ задействован в различных процедурах и процессах, разворачивающихся в окружающем мире (банковские и иные транзакции, документооборот, и пр.). Ординарный общедоступный ключ — это то, ради чего все, собственно, и затевалось. Например, секретный ключ из ординарной пары может использоваться для формирования ЭЦП различных документов — платежных поручений и т.д., а общедоступный — для проверки этой ЭЦП с последующим исполнением этих поручения при условии ее валидности.

Название этой пары соответствует ее назначению. Служебная пара выдаётся зарегистрированному субъекту DPKI. Заметим, что при формировании/проверке нулевой транзакции служебные ключи не применяются.

Еще раз уточним назначение ключей:

  1. Ключи кошелька применяются для формирования/проверки как нулевой, так и любой другой, отличной от нулевой, транзакции. Секретный ключ кошелька известен только владельцу кошелька, который одновременно является владельцем множества ординарных общедоступных ключей.
  2. Ординарный общедоступный ключ по своему назначению аналогичен общедоступному ключу, для которого выпускается сертификат в централизованной PKI.
  3. Служебная пара ключей принадлежит DPKI. Секретный ключ выдается зарегистрированным субъектам и используется при формировании ЭЦП транзакций (за исключением нулевой). Общедоступный применяется для проверки ЭЦП транзакции перед ее размещением в реестре.

Таким образом, имеется две группы ключей. В первую входят служебные ключи и ключи кошелька — имеют смысл только в контексте DPKI. Во вторую группу входят ординарные ключи — их область применения может различаться и обусловлена теми прикладными задачами, в которых они используются. При этом DPKI обеспечивает целостность и подлинность ординарных общедоступных ключей.

Например, может быть единой для всех. Примечание: Служебная ключевая пара может быть известна различным субъектам DPKI. Все ключи имеют свой смысл. Именно по этой причине при формировании подписи каждой ненулевой транзакции применяется два секретных ключа, один из которых ключ кошелька — он известен только владельцу кошелька, который одновременно является владельцем множества ординарных общедоступных ключей. И здесь не может быть злоупотреблений, например DOS-атаки, ведь владелец оплачивает каждую транзакцию. Например, всегда можно доказать, что транзакция была занесена в реестр зарегистрированным субъектом DPKI, так как подпись была сформирована в том числе и на секретном служебном ключе.

Так формируются данные третьего поля. Все транзакции, которые идут следом за нулевой, формируются похожим образом: общедоступный ключ (но не кошелька, как в случае с нулевой транзакцией, а из ординарной ключевой пары) прогоняется через две хеш-функции SHA256 и RIPEMD160. В пятом поле — общедоступный ключ из служебной ключевой пары. В четвертое поле заносится сопровождающая информация (например, информация о текущем статусе, сроках действия, временная отметка, идентификаторы используемых криптоалгоритмов и пр.). Обоснуем необходимость такого подхода. С его помощью потом будет проверяться ЭЦП, поэтому он тиражируется.

Хранение в пуле связано с определенным риском — данные транзакции могут быть фальсифицированы. Напомним, что транзакция заносится в пул и хранится там до тех пор, пока не будет обработана. Общедоступный ключ для проверки этой ЭЦП указывается в одном из полей транзакции в явном виде и впоследствии заносится в реестр. Владелец заверяет данные транзакции ЭЦП. Если подлинность и целостность обеспечивается исключительно посредством ЭЦП, то такой подлог останется незамеченным. Особенности обработки транзакции таковы, что злоумышленник способен изменить данные по своему усмотрению и затем заверить их при помощи своего секретного ключа, а парный общедоступный ключ для проверки ЭЦП указать в транзакции. Для этого достаточно занести в реестр подлинный общедоступный ключ владельца. Однако, если помимо ЭЦП существует дополнительный механизм, обеспечивающий одновременно архивирование и персистентность сохраняемой информации, то подлог возможно обнаружить. Поясним, как это работает.

С точки зрения ключей и ЭЦП возможны следующие варианты: Пусть злоумышленник выполняет подлог данных транзакции.

Злоумышленник размещает в транзакции свой общедоступный ключ при неизменной ЭЦП владельца.
2. 1. Злоумышленник формирует ЭЦП на своем секретном ключе и размещает в транзакции парный общедоступный ключ. Злоумышленник формирует ЭЦП на своем секретном ключе, но оставляет общедоступный ключ владельца без изменений.
3.

Смысл имеет только вариант 3, и если злоумышленник формирует ЭЦП на своём собственном секретном ключе, то он вынужден сохранять в транзакции парный общедоступный ключ, отличный от общедоступного ключа владельца. Очевидно, что варианты 1 и 2 бессмысленны, так как всегда будут обнаружены в ходе проверки ЭЦП. Для злоумышленника это единственный способ навязать сфальсифицированные данные.

Пусть данные заверяются ЭЦП при помощи секретного ключа из этой пары, а общедоступный ключ указывается в транзакции. Предположим, что владелец располагает фиксированной парой ключей — секретным и общедоступным. Тогда на подлог будет указывать то обстоятельство, что общедоступный ключ из транзакции не соответствует общедоступному ключу из реестра. Предположим также, что этот общедоступный ключ уже был ранее занесен в реестр и его подлинность достоверно подтверждена.

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

Благодаря использованию двух секретных ключей обеспечивается необходимый уровень безопасности — ведь служебный секретный ключ может быть известен другим пользователям, тогда как секретный ключ кошелька известен только владельцу ординарной ключевой пары. Транзакция заверяется ЭЦП — тут-то и понадобятся секретные ключи, и не один, а сразу два — служебный и кошелька. Мы назвали такую двух ключевую подпись “консолидированной” ЭЦП.

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

Для этого процесс проверки дополнен еще одной стадией — проверкой связности. Может возникнуть логичный вопрос: как проверить принадлежит ли транзакция конкретной цепочки с “корнем” в виде нулевой транзакции? Тут-то нам и понадобятся данные из первых двух полей, которые пока что мы обходили своим вниманием.

Для этого методом комбинированного хеширования вычисляется значение хеш-функция для данных из третьего, четвертого и пятого полей транзакции №2. Представим, что нам надо проверить, действительно ли транзакция №3 идет после транзакции №2. Все это тоже прогоняется через две хеш-функции SHA256 и RIPEMD160. Потом выполняется конкатенация данных из первого поля транзакции №3 и ранее полученное значение комбинированной хеш-функции для данных из третьего, четвертого и пятого полей транзакции №2. Более наглядно это показано на рисунках ниже. Если полученное значение совпадает с данным второго поля транзакции №2, то проверка пройдена и связность подтверждена.


Наглядная иллюстрация процесса формирования цепочки нотификатов представлена на следующем рисунке: В общих чертах технология формирования и занесения нотификата в реестр выглядит именно таким образом.

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

Итак, поскольку заявитель сам отправляет заявку на регистрацию нотификатов, которые хранятся не в базе данных УЦ, а в реестре, то основными архитектурными компонентами DPKI следует считать:

Реестр действующих нотификатов (РДН).
2. 1. Реестр приостановленных нотификатов (РПН). Реестр отозванных нотификатов (РОН).
3.

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

Таким образом, DPKI может оказаться если не проще, то по меньшей мере сравнимой с централизованным решением по сложности архитектуры.

Остается главный вопрос — какой реестр подойдет для реализации технологии?

Самый известный пример применения реестра — это сеть Биткойн. Главное требование к реестру — возможность формирования транзакций произвольного типа. Но в ней при реализации описанной выше технологии возникают определенные трудности: сказывается ограниченность существующего языка сценариев, отсутствие необходимых механизмов для обработки произвольных наборов данных, способов формирования транзакций произвольного типа, а также многое другое.

Мы в компании ENCRY попытались разрешить сформулированные выше проблемы и разработали реестр, который, на наш взгляд, обладает рядом преимуществ, а именно:

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

Если подходить упрощенно, то имеет место следующая последовательность действий:

  1. Заявитель регистрируется в DPKI и получает цифровой кошелек. Адрес кошелька — значение хеш-функции от общедоступного ключа кошелька. Секретный ключ кошелька известен только заявителю.
  2. Зарегистрированному субъекту предоставляется доступ к служебному секретному ключу.
  3. Субъект формирует нулевую транзакцию и заверяет ее ЭЦП с использованием секретного ключа кошелька.
  4. Если формируется отличная от нулевой транзакция, то заверяет ее ЭЦП с использованием двух секретных ключей: кошелька и служебного.
  5. Субъект отправляет транзакцию в пул.
  6. Узел сети ENCRY считывает транзакцию из пула и проверяет ЭЦП, а также связность транзакции.
  7. Если ЭЦП валидна и связность подтверждена, то подготавливает транзакцию для занесения в реестр.

Здесь реестр выступает в роли распределенной базы данных, в которой хранится информация о действующих, аннулированных и приостановленных нотификатах.

Технология проверки по открытым источникам хорошо известна. Конечно, децентрализация не панацея. Фундаментальная проблема первичной аутентификации пользователей никуда не исчезает: если в настоящее время проверкой заявителя занимаются ЦР, то в DPKI проверку предлагается делегировать участникам сообщества, и использовать финансовую мотивацию для стимуляции активности. Опять же вспомним ряд резонансных расследований интернет-издания Bellingcat. Эффективность такой проверки подтверждена на практике.

Но в общем складывается следующая картина: DPKI — это возможность исправить, если не все, то многие недостатки централизованной PKI.

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть