Подпись файлов через браузер

    В ряде проектов требуется подписывать файлы произвольного формата (например, конкурсную документацию в формате PDF) при загрузке их на сервер.
    Обычно требуется подпись по ГОСТ Р 34.10-2001, с применением цифровых сертификатов X.509. При этом саму подпись потом удобно хранить на сервере в формате CMS detached.
    Сразу хочется отметить, что задача это решена достаточно давно (КриптоПро CSP, CAPICOM, etc). Но есть нюансы, которые делают такое решение не всегда удобным. Для одного из проектов мы предложили решение по подписи файлов, которое реально облегчило жизнь конечным пользователям и техподдержке. О нем ниже.





    Общая схема решения приведена на картинке.
    Компоненты на клиенте.
    1. Рутокен ЭЦП в качестве аппаратного СКЗИ
    2. Рутокен Плагин для поддержки Рутокен ЭЦП в браузере + поддержка цифровых сертификатов

    На сервере используем модифицированный openssl + wrapper для ASP.NET. Использование openssl дает возможность перейти на сертифицированное СКЗИ МагПро КриптоПакет 2.1 без особых изменений серверной части.

    Описание протокола, по которому происходит подпись.
    1. Загрузка документа на сервер стандартными средствами браузера (или формирование документа на сервере, как часто бывает)
    2. Вычисление хэш-суммы от документа на сервере по ГОСТ Р 34.11-94 с помощью openssl
    3. Отсылка вычисленной хэш-суммы на клиент
    4. Подпись по ГОСТ Р 34.10-2001 хэш-суммы на клиенте закрытым ключом, связанным с сертификатом
    5. Отправка подписи и сертификата на сервер
    6. Проверка подписи
    7. Упаковка подписи и сертификата в формат CMS detached


    Теперь о технических средствах.
    Серверная библиотека-wrapper над openssl имеет следующее API:
    1. Функция вычисления хэш-суммы
      unsigned char* HashData(unsigned char* buffer, size_t size);
    2. Функция формирования CMS detached
      char* CreateSignedCMSDetached(unsigned char* signature, const char* cert);
    3. Функция проверки подписи не универсальна и реализована только для данного проекта, поэтому ее здесь описывать не буду


    Как видим, данные функции достаточно легко вызвать из ASP.NET (и не только).

    На клиенте подпись хэша осуществляется последовательностью вызовов Рутокен Плагин:
    1. Пользователь выбирает сертификат
    2. Найти закрытый ключ по сертификату
      getKeyByCertificate(deviceId, certId, resultCallback, errorCallback) → {string}
    3. Получить “тело” сертификата для отправки на сервер
      getCertificate(deviceId, certId, resultCallback, errorCallback) → {string}
    4. Подписать хэш с помощью закрытого ключа
      rawSign(deviceId, keyId, data, options, resultCallback, errorCallback) → {string}
      Возвращает подпись ГОСТ Р 34.10-2001 в hex от переданного хэша


    Хэш и сертификат отправляются на сервер.
    Решение является несложным как для разработчика, так и для конечного пользователя.
    «Актив»
    47,00
    Компания
    Поделиться публикацией

    Комментарии 115

      +2
      Чем ваше решение удобнее других? Все равно зависимость от рутокеновского плагина, дальше уже особой разницы нет, что вы там на сервере навертели.
        0
        В этом решении хэширование происходит на сервере и не ограничено производительностью токена.
          0
          Это (производительность токена) часто является проблемой? Чем такое решение проще для разработчика и конечного пользователя?
            0
            Хэшировать платежку можно и на токене, хэшировать какой-нибудь скан документа — малореально. В моем понимании, основное преимущество это отсутствие необходимости устанавливать сертифицированное криптосредство на рабочую станцию клиента. Это особенно актуально для «тетушек из бухгалтерии».
              0
              В моем понимании, основное преимущество это отсутствие необходимости устанавливать сертифицированное криптосредство на рабочую станцию клиента.

              Стоп-стоп, а подпись чем делается?

              Не важно, что вы подписываете, хеш документа или сам документ, средство подписания все равно должно быть сертифицированным (и здесь им выступает комбинация плагина с токеном).
                0
                Рутокен ЭЦП сертифицирование средство электронной подписи. В плагине нет крипты.
                  0
                  Значит, фраза «отсутствие необходимости устанавливать сертифицированное криптосредство на рабочую станцию клиента» — это жульничество. Вы «устанавливаете» токен в обоих случаях, так что нет никаких отличий (в этом аспекте).
                    –1
                    Если вам так хочется считать, то пожалуйста :) Просто есть совсем крошечная разница между «воткнуть токен в USB порт» и установить и настроить Крипто Про. Кто знает эту разницу, тот поймет о чем речь. :)
                      0
                      Просто есть совсем крошечная разница между «воткнуть токен в USB порт» и установить и настроить Крипто Про.

                      Вы хотите сказать, что для подписания файла (а не хеша файла) токена+плагин не достаточно, нужно обязательно криптопро ставить? Сайт рутокена утверждает, что можно подписать прямо на токене без криптопро.
                        0
                        Да. Если написать свой плагин. С поддержкой X.509 сертификатов открытого ключа ГОСТ Р 34.10-2001. Вы написали свой плагин что ли?
                          0
                          То есть существующий плагин умеет подписывать хеши, но не умеет хешировать документы, я правильно вас понял?

                          Странно, на сайте написано «Вычисление хеш-функции по ГОСТ Р 34.11-94».
                            0
                            Плагин все умеет. И один из возможных вариантов его использования здесь представлен.
                              0
                              Возвращаемся к сказанному выше: с точки зрения количества устанавливаемого на компьютер пользователя ПО варианты «подписываем хэш» и «подписываем файл» не отличаются никак. QED.
                                0
                                Это да. В случае использования Рутокен Плагин.
                                «Но есть нюанс, Петька» © :)
                                Описанные в комментах.
                                  0
                                  Не вижу никаких нюансов, уж простите.
                                    +1
                                    А вы его и не увидите. Можете только почувствовать, как Петька :)
                  0
                  По нашему законодательству на установку СКЗИ нужно иметь лицензию ФСБ на техническое обслуживание. При использовании СКЗИ никаких лицензий не нужно.
                  Что именно вы устанавливаете на рабочую станцию в случае Рутокен ЭЦП?
              0
              Проводилось ли тестирование по скорости между двумя вариантами?
              1) Подпись всего документа на клиенте (по той же процедуре, что и подписание хэша) и потом передача готовой подписи на сервер;
              2) Передача документа на сервер, хэширование на сервере, передача обратно на клиент, подпись на клиенте, передача строки на сервер;
                0
                Могу сказать что скорость хэширования токена (Рутокен ЭЦП) около 100 кб в секунду. То есть 10 мб файл будет хэшироваться грубо полторы минуты. На сервере это доли секунды. Для маленьких файлов предлагаемая схема не интересна, для больших весьма эффективна. А автору, конечно, надо бы приложить результаты тестов для показательности.
                  0
                  В первом упомянутом мною варианте отсутствует хэширование — там предполагается сразу выполнять подпись. Вполне возможно, что Рутокен оптимизирован на более быстрые операции подписи, чем на быстрое хэширование.
                    0
                    Подписать можно только хэш документа, по другому — никак.
                      0
                      Вы сильно ошибаетесь — на самом деле использование хэшей в процессе создания подписи как-раз связано с оптимизацией работы алгоритмов, использующих криптографию на асинхронных ключах. То есть можно использовать алгоритмы создания подписи и прямо на исходных данных, однако это многократно замедлит процесс.
                        0
                        Сертифицированная (используемая) в России криптография без хэша не работает.
                          0
                          Покажу как она работает.
                          1) Используем MS Crypto API + например Крипто-Про CSP;
                          2) Создаём контекст хэша данных функцией «CryptCreateHash»;
                          3) Устанавливаем любое значение хэша функцией «CryptSetHashParam(HP_HASHVAL)»;
                          4) Подписываем сообщение с помощью функции «CryptSignHash»;

                          Так что и здесь вы ошибаетесь.
                            0
                            То что эти действия завернуты в одну функцию сути не меняет. Данные хэшируются, затем подписываются.
                              0
                              Вы не поняли — в функцию «CryptSetHashParam(HP_HASHVAL)» можно передать любые данные. Они не хэшируются — они устанавливают как-бы результат выполнения функции хэширования.
                                0
                                Ну так криптопровайдер считает переданные данные хэшом. Что будет, если туда передать не 32 байта (размер хэша по ГОСТ Р 34.11-94)?
                                  0
                                  Попробуйте проверить :)
                                  0
                                  Переданные данные всегда хэшируются, не вводите в заблуждение сообщество. Не хотите это слушать от меня, проконсультируйтесь с тем кому вы доверяете.
                                    0
                                    Послушайте, я работаю с Crypto API более 10-ти лет. Являюсь единственным первичным автором ПО «КриптоАрм», автором статьи «Использование Crypto API», и много чего ещё. Поверьте, что в вопросах работы с MS Crypto API я являюсь очень весомым авторитетом :)

                                    А вам рекомендую почитать документацию по упомянутым мною функциям Crypto API.
                                      +1
                                      Это и огорчает…
                                0
                                Читаем RFC на ГОСТ Р 34.10-2001 www.rfc-editor.org/rfc/rfc5832.txt

                                6.1. Digital Signature Generation Process

                                It is necessary to perform the following actions (steps) according to
                                Algorithm I to obtain the digital signature for the message M
                                belonging to V_all:

                                Step 1 — calculate the message hash code M: H = h(M). (14)

                                Step 2 — calculate an integer alpha, binary representation of which
                                is the vector H, and determine e = alpha (mod q )
                                  0
                                  :) Спасибо, я читал. Вопрос не в ГОСТ, вопрос в неправильном высказывании «Сертифицированная (используемая) в России криптография без хэша не работает».

                                  P.S.: RFC не есть стандарт. Читайте настоящие ГОСТ, написанные по-русски.
                                    0
                                    Это RFC формировала группа людей, в которую входили разработчики ГОСТА 34.10-2001
                                      0
                                      В нашей стране стандартами являются документы ГОСТ.
                                      RFC = Request For Comments и являются только (в общем случае) информационными документами. Стандартами «Интернет сообщества» из них становятся только очень немногие документы, и их наименования начинаются с STD.
                              0
                              Асинхронные ключи?
                    0
                    Доступ к файлу на клиенте из JavaScript для передачи его на подпись какому-либо Active X или плагину — нетривиальная задача. Настройки безопасности браузера придется корректировать.А объекты работы с файлами из HTML 5 поддерживается не всеми версиями браузеров и тоже имеют свои нюансы. Здесь же такого нет, файл передается на сервер стандартными механизмами браузера, а на подпись приходит обычная строка.
                      0
                      Доступ к файлу на клиенте из JavaScript для передачи его на подпись какому-либо Active X или плагину — нетривиальная задача.

                      Это проблема ровно до тех пор, пока вы подписываете файл, переданный с клиентского компьютера, что не всегда так.

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

                      Ничто не мешает таким образом передать и весь файл.
                        0
                        Вы имеете ввиду кодирование файла в base64 на сервере и передача его в виде строки? Попробуйте таким способом подписать большой файл.
                          0
                          Это не единственный способ, и да, мы так делали.

                          Понимаете ли, если ваша схема направлена на решение проблемы «как подписать на клиенте большой файл» — это одно. Но говорить, что она вообще удобнее других вариантов — совсем другое.
                            0
                            >Но есть нюансы, которые делают такое решение не всегда удобным.

                            В статье было так написано.
                              0
                              Вот именно поэтому я и спросил, чем как и когда ваше решение выгодно. Пока что никаких случаев кроме «большой файл» я не вижу.
                                0
                                Минимум устанавливаемого на клиента софта. При этом быстрое легитимное вычисление хэш-функции.
                                  0
                                  Количество устанавливаемого софта не зависит от того, подписывается хэш или файл.
                              0
                              И поделитесь своим опытом. Очень интересно.
                                0
                                Самое банальное решение — это загрузка файла с сервера отдельным http-запросом (либо напрямую из подписывающего плагина, либо из хостовой страницы).
                                  0
                                  Ну то есть написать свой плагин — это проще, чем применить готовое решение?
                                    0
                                    Написано же «либо из хостовой страницы».
                                      0
                                      Дальше куда этот файл будет передаваться?
                                        0
                                        В плагин.
                                          0
                                          Плагин откуда взялся?
                                            0
                                            Оттуда же, откуда и в вашем сценарии.
                                              0
                                              Ваш плагин реализует функции СКЗИ или требует дополнительной установки СКЗИ?
                                                +1
                                                Пока мы пользовались своим плагином — требовал дополнительной установки СКЗИ. Но подход-то универсальный, до тех пор, пока на клиенте есть нечто, что может подписывать (не важно, рутокен, криптопро через капиком, еще какое-то решение) — он будет работать. И, повторюсь, это совершенно не зависит от того, подписывается файл (как в стандартной схеме) или хеш (как в вашей), методика подписания-то та же самая.
                      0
                      Витя, привет! разродились все-таки :)
                        0
                        Таки да )
                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Это не очень удобно — запускать отдельный процесс. Представьте, что пришло одновременно несколько запросов на подпись. Будет запущено несколько процессов, которые могут не поделить общие ресурсы.
                          • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            И еще — в openssl нет функционала упаковки в CMS, без вычисления подписи. Пришлось его немного «подпилить».
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                Может. Но не обязателен. В том числе и в detached. В случае необходимости атрибутов решение будет более сложным, так как там сначала хэшируются данные, потом формируется ASN1-структура атрибутов, в которую полученный хэш кладется как один из атрибутов и затем хэшируется уже эта структура. Подписывается второй хэш.
                                В данном решении атрибуты были не нужны.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Полученный хэш подписывается на закрытом ключе на клиенте. И вот эта подпись ГОСТ Р 34.10-2001 и сертификат уже упаковываются в CMS.
                                  0
                                  Вот пример дампа

                                  0: SEQUENCE {
                                  4 9: OBJECT IDENTIFIER signedData (1 2 840 113549 1 7 2)
                                  15 635: [0] {
                                  19 631: SEQUENCE {
                                  23 1: INTEGER 1
                                  26 12: SET {
                                  28 10: SEQUENCE {
                                  30 6: OBJECT IDENTIFIER GOST R 34.11-94 (1 2 643 2 2 9)
                                  38 0: NULL
                                  : }
                                  : }
                                  40 11: SEQUENCE {
                                  42 9: OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
                                  : }
                                  53 407: [0] {
                                  57 403: SEQUENCE {
                                  61 320: SEQUENCE {
                                  65 3: [0] {
                                  67 1: INTEGER 2
                                  : }
                                  70 1: INTEGER 1
                                  73 10: SEQUENCE {
                                  75 6: OBJECT IDENTIFIER '1 2 643 2 2 3'
                                  83 0: NULL
                                  : }
                                  85 84: SEQUENCE {
                                  87 11: SET {
                                  89 9: SEQUENCE {
                                  91 3: OBJECT IDENTIFIER countryName (2 5 4 6)
                                  96 2: PrintableString 'RU'
                                  : }
                                  : }
                                  100 15: SET {
                                  102 13: SEQUENCE {
                                  104 3: OBJECT IDENTIFIER localityName (2 5 4 7)
                                  109 6: PrintableString 'Moscow'
                                  : }
                                  : }
                                  117 34: SET {
                                  119 32: SEQUENCE {
                                  121 3: OBJECT IDENTIFIER organizationName (2 5 4 10)
                                  126 25: TeletexString 'OOO «Garant-Park-Telecom»'
                                  : }
                                  : }
                                  153 16: SET {
                                  155 14: SEQUENCE {
                                  157 3: OBJECT IDENTIFIER commonName (2 5 4 3)
                                  162 7: PrintableString 'Test CA'
                                  : }
                                  : }
                                  : }
                                  171 30: SEQUENCE {
                                  173 13: UTCTime 16/05/2013 10:40:14 GMT
                                  188 13: UTCTime 16/05/2014 10:40:14 GMT
                                  : }
                                  203 17: SEQUENCE {
                                  205 15: SET {
                                  207 13: SEQUENCE {
                                  209 3: OBJECT IDENTIFIER commonName (2 5 4 3)
                                  214 6: PrintableString 'ghjghj'
                                  : }
                                  : }
                                  : }
                                  222 99: SEQUENCE {
                                  224 28: SEQUENCE {
                                  226 6: OBJECT IDENTIFIER GOST R 34.10-2001 (1 2 643 2 2 19)
                                  234 18: SEQUENCE {
                                  236 7: OBJECT IDENTIFIER
                                  : id-GostR3410-2001-CryptoPro-A-ParamSet (1 2 643 2 2 35 1)
                                  245 7: OBJECT IDENTIFIER
                                  : id-GostR3411-94-CryptoProParamSet (1 2 643 2 2 30 1)
                                  : }
                                  : }
                                  254 67: BIT STRING, encapsulates {
                                  257 64: OCTET STRING
                                  : A5 84 B2 8D 24 BA 17 E6 72 08 D0 9F B5 34 30 63
                                  : 19 3B 74 AC 17 AF 66 FA 06 6C FD 8D C9 31 1B BC
                                  : E1 31 10 8C A7 13 A7 E2 BC 8E 01 11 8C 0A 7E B2
                                  : 76 44 7B 0B B5 AC 05 70 1D 8C A6 4D BE 45 13 DA
                                  : }
                                  : }
                                  323 60: [3] {
                                  325 58: SEQUENCE {
                                  327 29: SEQUENCE {
                                  329 3: OBJECT IDENTIFIER extKeyUsage (2 5 29 37)
                                  334 22: OCTET STRING, encapsulates {
                                  336 20: SEQUENCE {
                                  338 8: OBJECT IDENTIFIER
                                  : clientAuth (1 3 6 1 5 5 7 3 2)
                                  348 8: OBJECT IDENTIFIER
                                  : emailProtection (1 3 6 1 5 5 7 3 4)
                                  : }
                                  : }
                                  : }
                                  358 11: SEQUENCE {
                                  360 3: OBJECT IDENTIFIER keyUsage (2 5 29 15)
                                  365 4: OCTET STRING, encapsulates {
                                  367 2: BIT STRING 2 unused bits
                                  : '100101'B
                                  : }
                                  : }
                                  371 12: SEQUENCE {
                                  373 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19)
                                  378 1: BOOLEAN TRUE
                                  381 2: OCTET STRING, encapsulates {
                                  383 0: SEQUENCE {}
                                  : }
                                  : }
                                  : }
                                  : }
                                  : }
                                  385 10: SEQUENCE {
                                  387 6: OBJECT IDENTIFIER '1 2 643 2 2 3'
                                  395 0: NULL
                                  : }
                                  397 65: BIT STRING
                                  : 81 87 18 CD D1 B6 21 5F 21 2E 5C 86 53 A6 55 F0
                                  : C4 63 1C 11 D2 04 CC 59 FA F3 8C 1F 42 09 5A 2F
                                  : F6 F3 EC C9 17 9F FB 9B 7F 65 75 31 FB 61 AE DD
                                  : 83 7E 3F 6E C9 33 FE B0 76 32 AA 38 F6 B3 5A 9C
                                  : }
                                  : }
                                  464 187: SET {
                                  467 184: SEQUENCE {
                                  470 1: INTEGER 1
                                  473 89: SEQUENCE {
                                  475 84: SEQUENCE {
                                  477 11: SET {
                                  479 9: SEQUENCE {
                                  481 3: OBJECT IDENTIFIER countryName (2 5 4 6)
                                  486 2: PrintableString 'RU'
                                  : }
                                  : }
                                  490 15: SET {
                                  492 13: SEQUENCE {
                                  494 3: OBJECT IDENTIFIER localityName (2 5 4 7)
                                  499 6: PrintableString 'Moscow'
                                  : }
                                  : }
                                  507 34: SET {
                                  509 32: SEQUENCE {
                                  511 3: OBJECT IDENTIFIER organizationName (2 5 4 10)
                                  516 25: TeletexString 'OOO «Garant-Park-Telecom»'
                                  : }
                                  : }
                                  543 16: SET {
                                  545 14: SEQUENCE {
                                  547 3: OBJECT IDENTIFIER commonName (2 5 4 3)
                                  552 7: PrintableString 'Test CA'
                                  : }
                                  : }
                                  : }
                                  561 1: INTEGER 1
                                  : }
                                  564 10: SEQUENCE {
                                  566 6: OBJECT IDENTIFIER GOST R 34.11-94 (1 2 643 2 2 9)
                                  574 0: NULL
                                  : }
                                  576 10: SEQUENCE {
                                  578 6: OBJECT IDENTIFIER GOST R 34.10-2001 (1 2 643 2 2 19)
                                  586 0: NULL
                                  : }
                                  588 64: OCTET STRING
                                  : 97 6A CC 9D 47 45 FE 07 FC BC 60 14 C3 B2 EE 01
                                  : 79 C2 64 74 B0 BF E7 62 03 80 4C DA 12 FE 89 BB
                                  : D0 96 DC C7 73 A4 8A B7 FC A1 19 D7 43 40 D7 82
                                  : 5F BD D4 3E 95 64 99 16 FA 1B 94 DF C2 4B 9E EE
                                  : }
                                  : }
                                  : }
                                  : }
                                  : }
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      В случае отсутствия атрибутов хэш не сохраняется. Он «неявно» входит в подпись.

                                      576 10: SEQUENCE {
                                      578 6: OBJECT IDENTIFIER GOST R 34.10-2001 (1 2 643 2 2 19)
                                      586 0: NULL
                                      : }
                                      588 64: OCTET STRING
                                      : 97 6A CC 9D 47 45 FE 07 FC BC 60 14 C3 B2 EE 01
                                      : 79 C2 64 74 B0 BF E7 62 03 80 4C DA 12 FE 89 BB
                                      : D0 96 DC C7 73 A4 8A B7 FC A1 19 D7 43 40 D7 82
                                      : 5F BD D4 3E 95 64 99 16 FA 1B 94 DF C2 4B 9E EE
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          0
                                          Да. Если CMS формируется без «signed» атрибутов. Частный случай. Хотя он и распространен.
                                        0
                                        Вот base64

                                        MIICigYJKoZIhvcNAQcCoIICezCCAncCAQExDDAKBgYqhQMCAgkFADALBgkqhkiG
                                        9w0BBwGgggGXMIIBkzCCAUCgAwIBAgIBATAKBgYqhQMCAgMFADBUMQswCQYDVQQG
                                        EwJSVTEPMA0GA1UEBxMGTW9zY293MSIwIAYDVQQKFBlPT08gIkdhcmFudC1QYXJr
                                        LVRlbGVjb20iMRAwDgYDVQQDEwdUZXN0IENBMB4XDTEzMDUxNjEwNDAxNFoXDTE0
                                        MDUxNjEwNDAxNFowETEPMA0GA1UEAxMGZ2hqZ2hqMGMwHAYGKoUDAgITMBIGByqF
                                        AwICIwEGByqFAwICHgEDQwAEQKWEso0kuhfmcgjQn7U0MGMZO3SsF69m+gZs/Y3J
                                        MRu84TEQjKcTp+K8jgERjAp+snZEewu1rAVwHYymTb5FE9qjPDA6MB0GA1UdJQQW
                                        MBQGCCsGAQUFBwMCBggrBgEFBQcDBDALBgNVHQ8EBAMCAqQwDAYDVR0TAQH/BAIw
                                        ADAKBgYqhQMCAgMFAANBAIGHGM3RtiFfIS5chlOmVfDEYxwR0gTMWfrzjB9CCVov
                                        9vPsyRef+5t/ZXUx+2Gu3YN+P27JM/6wdjKqOPazWpwxgbswgbgCAQEwWTBUMQsw
                                        CQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MSIwIAYDVQQKFBlPT08gIkdhcmFu
                                        dC1QYXJrLVRlbGVjb20iMRAwDgYDVQQDEwdUZXN0IENBAgEBMAoGBiqFAwICCQUA
                                        MAoGBiqFAwICEwUABECXasydR0X+B/y8YBTDsu4BecJkdLC/52IDgEzaEv6Ju9CW
                                        3MdzpIq3/KEZ10NA14JfvdQ+lWSZFvoblN/CS57u
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                              0
                                              Да
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                  +1
                                  Мне одному кажется, что тут нарушается сама идея подписи? Клиент читает документ, говорит «ок, вроде все хорошо», отсылает его на какой-то сервер. Тот считает хэш непонятно от чего (от завещания на квартиру клиента) и отправляет обратно. А клиент такой наивный, что подписывает это завещание.
                                  В последнее время все популярней становится идея подписи документа на отдельном устройстве с экраном, которое еще раз показывает документ перед подписью. Чтобы вирус на компе не смог скормить в подписывалку модифицированный документ. А тут клиент какой-то совсем наивный.
                                  Может тогда клиент просто свой приватный ключ серверу отдаст? Пусть он все подписывает и токен не нужен :)
                                    0
                                    Ну собственно да, эту всю конструкцию надо бы отдельно сертифицировать, чтобы выданная ей подпись считалась юридически значимой.
                                      0
                                      Да суть не в том, на сколько доверенный сервер. По дороге очень много уязвимых точек. Я не понимаю какая тут модель угроз.
                                      Сама идея использования токенов состоит в том, что если злоумышленник умудрится подсадить вирус на комп (например в процесс браузера), он не сможет достать приватный ключ и подписать какую-нибудь фигню. А тут ему вообще не надо ничего доставать, подписывай сколько угодно чего угодно :)
                                      Может быть где-то есть хотя бы use-case'ы для модели угроз? Вы же что-то анализировали прежде чем разрабатывать.
                                        0
                                        А если речь идет не о защите, а как у нас обычно делается «есть сертификат — значит безопасно», то во встек вообще любую фигню можно протолкнуть :)
                                          0
                                          Я вообще вижу только один более-менее безопасный вариант, как можно сделать хэширование на доверенном сервере: надо чтобы токен использовался как смарт-карта и сам проводил взаимную аутентификацию с сервером, используя комп, браузер и интернет как недоверенный транспорт. Отдельный сессионный ключ отдать браузеру и использовать его для шифрования транспорта с сервером. И отдельный сессионный ключ использовать для общения непосредственно токена и сервера (получение хэша). Все равно остается уязвимое место — браузер, который может показать пользователю не то, что есть на самом деле, но, по крайней мере, мы не падаем в безопасности относительно модели с локальной подписью на токене.
                                          Как я уже говорил, чтобы избавиться от последнего уязвимого звена, нужно выпустить токены с мониторчиком :)
                                            0
                                            Вы описали действительно правильное решение! На сколько я знаю, именно такое решение и ожидается после сертификации Secure Messaging-а в новой версии Рутокен ЭЦП. Ну а токены с мониторчиками есть — http://www.rutoken.ru/products/all/rutoken-pinpad/
                                              +1
                                              Клевая штука.
                                            0
                                            Все равно это противоречит самой идее PKI. Изначально идея состоит в том, чтобы никто, кроме самого клиента, не мог сформировать подпись. Большинство заморочек PKI связаны с генерацией приватного ключа на клиенте. А тут мы расширяем зону доверия на сервер. Если он супер-доверенный, то зачем тогда токен и PKI? Может быть проще было оставить приватный ключ на сервере? При этом безопасность системы только возрастет. Клиент и так полностью доверяет серверу, так как тот для него формирует хэш, т.е. клиент просто подписывает не глядя. Но, нам приходится этот хэш туда-сюда гонять, что снижает безопасность. Проще уж сделать так, чтобы приватный ключ лежал на доверенном сервере: его и защищать проще и хэш не надо передавать. Вопрос только в защите канала, по которому клиенту документ отображается, но его и так надо защищать…
                                            В общем какая-то фиговая идея, на мой взгляд.
                                              0
                                              >Может быть проще было оставить приватный ключ на сервере
                                              Проще. Но меры по защите на сервере закрытого ключа (что-то типа применения HSM) могут стоить для некоторых проектов дороже, чем использование токенов на клиенте. Соответственно кража ключа подразумевает другой уровень угроз по сравнению с подписью хэша, сформированного на сервере.
                                                0
                                                А для таких проектов зачем хеширование на сервере? Чем не устраивало такое же программное хэширование на клиенте? При этом не надо иметь «супер-доверенный» сервер, клиент должен доверять только самому себе и т.д.
                                                Можете пояснить в чем выигрышь от вашего решения?
                                                  0
                                                  Программное хэширование (с легитимной реализацией хэш-функции) предполагает инсталляцию СКЗИ на рабочее место пользователя.
                                                    0
                                                    Т.е. проблема в бумажке? :) Тогда так и надо написать: мы решили юридическую проблему, которая не имеет отношения к реальной защите :)
                                                      0
                                                      Всем же понятно, что можно было в драйвер рутокена или в плагин браузера добавить хеширование и ничего бы не изменилось, кроме, возможно, юридического статуса
                                                        +1
                                                        Эм… Кстати, я серьезно по поводу «написать». Добавьте в статью разъясняющий дисклеймер. Мол у нас токен тормозной, хеш считает медленно. Добавить считалку хеша в драйвер/плагин не можем по юридическим причинам. Решили унести подсчет хеша на сервер. Естественно, при этом клиент должен всецело доверять серверу. Идея PKI при этом, пострадала. Приватный ключ на сервер не унесли, так как защищать его дорого, хоть и эффективней. В будущей версии (перед сертификацией) добавим взаимную аутентификацию рутокена и сервера, чтобы хоть как-то подтянуть безопасность к модели с локальным токеном.
                                                        А то какая-то не честная статья получается.
                                                          0
                                                          Отлично написано. Вот только клиент должен ещё и доверять каналу передачи с клиента на сервер и обратно. А это без использования выделенных каналов или шифрования передаваемых данных добиться невозможно. Так что один из компонентов всей системы всегда будет недоверенным. А следовательно и вся система в целом.
                                                            0
                                                            Все верно. Выше у меня написано, что нужны два сессионных ключа: один для защиты канала браузер-сервер, второй для защиты канала рутокен-сервер. Под взаимной аутентификацией, естественно, подразумевается еще и выроботка ключей, т.е. Mutual Authentication and Key Agreement protocol.
                                                    0
                                                    И еще один момент. В случае подписи через браузер вы в любом случае расширяете зону доверия на сервер. Так как по факту сервер может сформировать такую страницу, которая покажет одни данные, а подпишет другие.
                                                      0
                                                      Вы имеете в виду, что страница может отправить в плагин один файл, а пользователю дать почитать другой? Чем это отличается от ситуации с вирусом в браузере? Выше многократно говорилось, что единственный хороший вариант защиты канала отображения — это использование отдельного девайса с мониторчиком. Вариант похуже — программный контроль за всем и вся + комплекс административных мер.
                                                      Если мы считаем, что браузер доверенный и в нем нет закладок, то ничего не стоит из плагина проконтролировать этот момент. Например, проверить, что страничка подходит под какой-то шаблон. Можно просто отображать документ непосредственно из плагина перед подписью. На крайняк пользователь всегда может почитать исходник странички. По крайней мере, это не концептуальная проблема и с ней можно бороться. И я удивлен, что вы этого не делаете.
                                                        0
                                                        На самом деле, «условно правильное» решение подобной проблемы — это механизм который не только подписывает, но и отображает документ. Соответственно, именно этот механизм целиком (вместе с отображением и подписанием) проверяется на невозможность атаки «показываем не тот документ, который подписываем» и сертифицируется.
                                                          0
                                                          Ага, вы абсолютно правы. Это хорошее обобщение под «отдельным девайсом с мониторчиком» и «плагином, отображающим документ перед подписью».
                                                  0
                                                  Лучше по порядку. Схемы с хранением закрытых ключей на сервере существуют, они вполне легетимны. Все упирается в доверие сервису. Плюс к тому необходимо обеспечить защиту канала и аутентификацию сервера. Вариантов реализации много. Вторая проблема Man in the Browser, в случае заражения компьютера пользователя. В этом случае проблема с токеном существует при любой схеме использования, что в общем-то и встречается в существующей действительности. Зловред может подсунуть на подпись любой документ и в «классической» схеме, и в описанной. И действительно, гарантировано решить эту проблему может только использование доверенных устройств с отдельным экраном.
                                                    0
                                                    Вот, я как раз выше написал про хранение приватного ключа на сервере. Это упростит жизнь клиенту и поднимет безопасность. Зачем в данной схеме токен я вообще не понимаю.
                                                      0
                                                      Ну тоесть токен можно использовать для защиты канала с сервером, а не для хранения приватного ключа и подписи.
                                                        0
                                                        В действительности эту проблему можно решить сформировав доверенную среду. То есть выполнив комплекс административных и технических мер на месте создания ЭЦП. Какие-то «устройства с отдельным экраном» это только малая часть комплекса и, скорее всего, избыточная ибо в по-настоящему доверенной среде проблемы вида «Man-in-a-browser» должны исключаться административными и техническими средствами полностью. А использование «устройств с экранами» у обычных пользователей представляется избыточно дорогим.
                                                          0
                                                          Практика показывает, что создание доверенной среды на рабочем месте видится невозможным :)
                                                            0
                                                            Все правильно. Способ защиты всегда зависит от модели угроз.
                                                            В данном случае проблема в расширении зоны доверия пользователя на сервер. Это делает саму идею PKI и подпись хэша на клиенте бессмысленным занятием. Т.е. мониторчики и другие способы защиты канала отображения — это вторично :)
                                                              0
                                                              Во всяких серьезных применениях так и делают: СРД, отдельная сеть, без доступа в интернет (еще и на аппаратных шифраторах), контроль целостности ОС при старте, т.е. замок, автоматчик, стреляющий в коленку, при попытке слить информацию и т.д. Все это пипец как дорого, а главное — геморрой для конечного пользователя.
                                                            0
                                                            Хорошее замечание, у меня также возникло сомнение по этому поводу.

                                                            По сути, в приведённой схеме, пользовательский Рутокен ЭЦП подписывает хеш от некоторого сообщения, которое отнюдь не факт, что является исходным.
                                                              0
                                                              Данное решение не претендует на универсальность.
                                                              Но имеет право на применение в проектах, в которых, грубо говоря, подпись — не подтверждение перевода денег, а согласие клиента на обслуживание в данном ЖЭКе. Это условная аналогия.
                                                                0
                                                                Я немного обобщу в этом комментарии моё личное видение на это решение.

                                                                Использование RuToken оправдано исключительно только в виде защищённого хранилища ключей, без возможности копирования и не санкционированного изъятия. Использование в виде устройства вида «cryptography-on-board» упирается в вопрос производительности на больших объёмах. При нарастании скорости сети и среднего объёма файлов в конечном итоге вопрос производительности станет непреодолимым препятствием для дальнейшего развития RuToken в качестве устройства, выполняющего криптографические преобразования.

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

                                                                P.S.: Видел несколько раз выше в комментариях вопрос вида «А вы сами плагин писали?». Отвечу заранее — да, писал :) И даже написал. И даже несколько. И они даже работают :)
                                                                  0
                                                                  В плагине есть программная реализация хэш-функции ГОСТ Р 34.11-94. Несертифицированная.
                                                                    0
                                                                    А в чем сложность была взять у Анкада сертифицированную? :)
                                                                      0
                                                                      А самое главное, зачем она там, если ее нельзя применять, чтобы по ушам не получить?
                                                                        0
                                                                        Потому что в некоторых проектах не настолько важна «юридическая чистота»
                                                                      0
                                                                      Да мы уже поняли. Ваши плагины подписывают данные без вычисления хэш-функции. На, как вы выразились, «асинхронных» ключах.
                                                                        0
                                                                        Ну ладно Вам, человек плохо разбирается в криптухе, зачем гнобить-то? :) Во многих аспектах он действительно прав.
                                                                          0
                                                                          О как :) Мелкие нападки.
                                                                          Тогда считайте, что компания «Актив» теперь приобрела в моём лице критика всех статей, появляющихся в их блоге на Хабре.
                                                                            0
                                                                            Фига се мелкие :) Вы лично мне сделали день :) Но в целом ваша концепция представляется верной :)
                                                                              0
                                                                              Крупные? :)
                                                                              Хорошо, тогда компания «Актив» приобрела в моём лице критика и отдельных комментариев лиц, работающих в данной компании.
                                                                  0
                                                                  Удалил. Уже ответили…
                                                                    0
                                                                    Кстати, предлагаю обсудить основную проблему: почему рутокен так медленно считает хеш? В чем сложность поставить процессор по-новее? Более того, я, конечно, могу ошибаться, но Ваши обороты вполне позволяют просто заказать свой чип (полузаказной) с аппаратным гостом.
                                                                    Понятно, что ради небольшого проекта никто не станет заморачиваться, но глобально… Расскажите нам о Ваших планах, пожалуйста :)

                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                    Самое читаемое