{"id":37008493,"url":"https://github.com/mitwork/kalkan","last_synced_at":"2026-01-14T00:50:05.556Z","repository":{"id":199821014,"uuid":"703488660","full_name":"mitwork/kalkan","owner":"mitwork","description":"Laravel package for Kalkan (NCANode, NCALayer)","archived":false,"fork":false,"pushed_at":"2025-02-24T20:26:51.000Z","size":246,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"1.x","last_synced_at":"2025-10-09T00:57:39.280Z","etag":null,"topics":["cryptography","digital-signature","kalkan","kalkancrypt","laravel","ncalayer","ncanode"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitwork.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-11T10:39:31.000Z","updated_at":"2025-04-11T22:02:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"0de0ddaa-51b5-4289-86d2-b0c266ba79c1","html_url":"https://github.com/mitwork/kalkan","commit_stats":null,"previous_names":["mitwork/kalkan"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/mitwork/kalkan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitwork%2Fkalkan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitwork%2Fkalkan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitwork%2Fkalkan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitwork%2Fkalkan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitwork","download_url":"https://codeload.github.com/mitwork/kalkan/tar.gz/refs/heads/1.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitwork%2Fkalkan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28407125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","digital-signature","kalkan","kalkancrypt","laravel","ncalayer","ncanode"],"created_at":"2026-01-14T00:50:05.296Z","updated_at":"2026-01-14T00:50:05.510Z","avatar_url":"https://github.com/mitwork.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kalkan Laravel Package\n\n---\n\n![License:MIT](https://img.shields.io/badge/license-MIT-green.svg)\n![Packagist Downloads](https://img.shields.io/packagist/dt/mitwork/kalkan)\n[![Build Tests](https://github.com/mitwork/kalkan/actions/workflows/tests.yml/badge.svg)](https://github.com/mitwork/kalkan/actions/workflows/tests.yml/badge.svg)\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/mitwork/kalkan)\n\n---\n\nДанная библиотека реализует следующие возможности:\n\n- Подписание XML данных;\n- Подписание бинарных данных (CMS);\n- Проверка и извлечение подписанных данных;\n- QR, кросс-подписание.\n\nВнешние зависимости:\n\n- [NCALayer](https://ncl.pki.gov.kz/) - подписание данных на стороне клиента в браузере;\n- [NCANode](https://v3.ncanode.kz/) - проверка, валидация и извлечение подписанных данных;\n- eGov mobile ([App Store](https://apps.apple.com/kz/app/egov-mobile/id1476128386), [PlayMarket](https://play.google.com/store/apps/details?id=kz.mobile.mgov\u0026hl=ru)), eGov business ([App Store](https://apps.apple.com/kz/app/egov-business/id1597880144), [PlayMarket](https://play.google.com/store/apps/details?id=kz.mobile.mgov.business\u0026hl=ru)) - QR и кросс-подписание.\n\nДля возможности QR и кросс-подписания ваша информационная система должна быть подключена к услуге [Сервис QR подписания посредством приложения Egov Mobile](https://sb.egov.kz/smart-bridge/services/passport/NITEC-S-5096),\nи внешний адрес (адреса) должны быть добавлены на стороне оператора услуги.\n\nНа этапе тестирования может понадобиться установить тестовые сборки приложений eGov mobile, eGov business - напрямую для OS Android, \nлибо с помощью [TestFlight](https://developer.apple.com/testflight/) по ссылке-приглашению оператора сервиса. Для тестирования кросс-ссылок, так же будет\nнеобходимо указать корректные ссылки с идентификаторами тестовых приложений.\n\n## Поддерживаемые версии\n\n- PHP - 8.2, 8.3, 8.4;\n- Laravel - 10, 11, 12.\n\n## Установка\n\nДанный пакет устанавливается с помощью composer в существующий или новый [Laravel](https://laravel.com/)-проект командой:\n\n```shell\ncomposer require mitwork/kalkan\n```\n\n## Настройка\n\nДля возможности внесения изменений необходимо опубликовать конфигурацию в проект командой:\n\n```shell\nphp artisan vendor:publish --tag kalkan-config\n```\n\nПараметры задаются и/или переопределяются в файле `config/kalkan.php`:\n\n```php\n\u003c?php\n\nreturn [\n    'ncanode' =\u003e [\n        'host' =\u003e env('NCANODE_HOST', 'http://localhost:14579'),\n    ],\n    'links' =\u003e [\n        'prefix' =\u003e 'mobileSign:',\n        'mobile' =\u003e 'https://mgovsign.page.link/?link=%s\u0026isi=1476128386\u0026ibi=kz.egov.mobile\u0026apn=kz.mobile.mgov',\n        'business' =\u003e 'https://egovbusiness.page.link/?link=%s\u0026isi=1597880144\u0026ibi=kz.mobile.mgov.business\u0026apn=kz.mobile.mgov.business',\n    ],\n    'actions' =\u003e [\n        'store-document' =\u003e 'store-document',\n        'store-request' =\u003e 'store-request',\n        'generate-qr-code' =\u003e 'generate-qr-code',\n        'generate-cross-link' =\u003e 'generate-cross-link',\n        'generate-service-link' =\u003e 'generate-service-link',\n        'prepare-content' =\u003e 'prepare-content',\n        'process-content' =\u003e 'process-content',\n        'check-document' =\u003e 'check-document',\n        'check-request' =\u003e 'check-request',\n    ],\n    'options' =\u003e [\n        'description' =\u003e 'Текст для пользователя',\n        'organisation' =\u003e [\n            'nameRu' =\u003e 'АО ТЕСТ',\n            'nameKz' =\u003e 'ТЕСТ АҚ',\n            'nameEn' =\u003e 'JS TEST',\n            'bin' =\u003e '123456789012',\n        ],\n        'auth' =\u003e [\n            'type' =\u003e 'None', // Bearer\n            'token' =\u003e '',\n        ],\n    ],\n    'ttl' =\u003e 180,\n];\n```\n\nгде:\n\n- `ncanode.host` - адрес и порт для подключения к NCANode;\n- `links.prefix` - префикс для формирования ссылки в QR-code;\n- `links.mobile` - шаблон для формирования кросс-ссылки при подписании в приложении _eGov mobile_;\n- `links.business` - шаблон для формирования кросс-ссылки при подписании в приложении _eGov business_;\n- `actions` - именованные маршруты для взаимодействия с приложениями при QR и кросс-подписании;\n- `options.description` - название запроса или информационной системы;\n- `options.organisation` - сведения об организации;\n- `auth.type` - тип авторизации при формировании сервисных ссылок для QR-подписания, допустимые значения - `None`, `Bearer`;\n- `auth.token` - токен авторизации, в случае если он не задан для запроса - будет сформирован уникальный одноразовый токен;\n- `ttl` - время жизни одноразовых ссылок (в секундах).\n\n## Использование\n\n### Подписание и проверка XML данных\n\nДанный пример подписания применим для подписания на бэкенде, когда ключ ЭЦП находится на сервере.\nДля проверки подлинности данных, подписанных через NCALayer необходимо передавать подписанные данные через HTTP-запрос.\n\n```php\n\u003c?php\n\nnamespace App\\Controllers;\n\nuse \\Mitwork\\Kalkan\\Services\\KalkanSignatureService;\nuse \\Mitwork\\Kalkan\\Services\\KalkanValidationService;\n\nclass TestXmlController extends Controller\n{\n    function __construct(\n        public KalkanSignatureService $signatureService,\n        public KalkanValidationService $validationService,\n    )\n    {\n        //\n    }\n    \n    function testXmlSign(): string\n    {\n        $xml = '\u003c?xml...';\n        $key = 'base64...';\n        $password = 'password';\n        \n        $result = $this-\u003esignatureService-\u003esignXml($xml, $key, $password);\n        \n        // dd($result);\n        // \u003c?xml...\n        \n        return $result;\n    }\n    \n    function testXmlVerify(): bool\n    {\n        $signedXml = $this-\u003etestXmlSign();\n        \n        $result = $this-\u003evalidationService-\u003everifyXml($signedXml);\n        \n        // dd($result);\n        // true\n        \n        return $result;\n    }\n}\n```\n\n### Подписание, проверка и извлечение CMS данных\n\nДанный пример подписания применим для подписания на бэкенде, когда ключ ЭЦП находится на сервере.\nДля проверки подлинности данных, подписанных через NCALayer необходимо передавать подписанные данные через HTTP-запрос.\n\n```php\n\u003c?php\n\nnamespace App\\Controllers;\n\nuse \\Mitwork\\Kalkan\\Services\\KalkanSignatureService;\nuse \\Mitwork\\Kalkan\\Services\\KalkanValidationService;\nuse \\Mitwork\\Kalkan\\Services\\KalkanExtractionService;\n\nclass TestCmsController extends Controller\n{\n    function __construct(\n        public KalkanSignatureService $signatureService,\n        public KalkanValidationService $validationService,\n        public KalkanExtractionService $extractionService,\n    )\n    {\n        //\n    }\n    \n    function testCmsSign(): string\n    {\n        $data = 'base64...';\n        $key = 'base64...';\n        $password = 'password';\n        \n        $result = $this-\u003esignatureService-\u003esignCms($data, $key, $password);\n        \n        // dd($result);\n        // base64...\n        \n        return $result;\n    }\n    \n    function testCmsVerify(): bool\n    {\n        $cms = 'base64...';\n        $data = 'base64...';\n        \n        $result = $this-\u003evalidationService-\u003everifyCms($cms, $data);\n        \n        // dd($result);\n        // true\n        \n        return $result;\n    }\n    \n    function testCmsExtract(): string\n    {\n        $cms = 'base64...';\n        \n        $result = $this-\u003eextractionService-\u003eextractCms($cms);\n        \n        // dd($result);\n        // base64...\n        \n        return $result;\n    }\n}\n```\n\n### QR, кросс-подписания\n\nПоскольку взаимодействие происходит по протоколу HTTP, данный пакет кроме сервисов содержит так же и готовые `Http\\Actions` для выполнения всех требуемых шагов.\n\n- `POST` `/api/documents` - загрузка документов;\n- `POST` `/api/requests` - формирование запроса;\n- `GET` `/api/requests/generate/{id}` - генерация сервисной ссылки;\n- `GET` `/api/requests/qr-code/{id}` - формирование QR-кода;\n- `GET` `/api/requests/links/{id}` - формирование кросс-ссылок;\n- `GET` `/api/requests/{id}` - работа с данными - отдача;\n- `PUT` `/api/requests/{id}` - работа с данными - обработка;\n- `GET` `/check/document/{id}` - проверка статуса подписания документа;\n- `GET` `/check/request/{id}` - проверка статуса заявки.\n\nДля использования готовых методов, необходимо указать маршруты в `routes/api.php` описанные в [отдельном документе](docs/ROUTES_AND_ACTIONS.md) или [исходном коде](routes/api.php).\n\nПри необходимости можно переопределить любой из шагов, указав собственный обработчик. Подробнее о каждом из шагов написано в разделах ниже.\n\n#### QR-подписание\n\nДанный механизм позволяет подписывать данные с помощью смартфона с использованием приложений eGov mobile или eGov business, \nкогда проект открыт в браузере компьютера или планшета.\n\n**Основные шаги:**\n\n1) [Загрузка документов](docs/STEP_10_STORE_DOCUMENT.md) - данный шаг опционален, документы можно отправить на шаге 2;\n2) [Формирование запроса](docs/STEP_20_STORE_REQUEST.md) и [генерация сервисной ссылки](docs/STEP_21_GENERATE_SERVICE_LINK.md);\n3) [Формирование QR-кода](docs/STEP_22_GENERATE_QR_CODE.md);\n4) Считывание QR-кода мобильным приложением;\n5) [Получение подписываемых данных](docs/STEP_30_PREPARE_CONTENT.md) мобильным приложением;\n6) Подписание данных;\n7) [Обработка подписанных данных](docs/STEP_40_PROCESS_CONTENT.md);\n8) [Проверка статуса подписания документа](docs/STEP_50_CHECK_DOCUMENT.md).\n\n#### Кросс-подписание\n\nДанный механизм позволяет подписывать данные с помощью смартфона с использованием приложений eGov Mobile или eGov Business,\nкогда проект (сайт) открыт на самом смартфоне.\n\n**Основные шаги:**\n\n1) [Загрузка документов](docs/STEP_10_STORE_DOCUMENT.md) - данный шаг опционален, документы можно отправить на шаге 2;\n2) [Формирование запроса](docs/STEP_20_STORE_REQUEST.md) и [генерация сервисной ссылки](docs/STEP_21_GENERATE_SERVICE_LINK.md);\n3) [Формирование кросс-ссылок](docs/STEP_23_GENERATE_CROSS_LINKS.md);\n4) Переход по кросс-ссылке в мобильное приложение;\n5) [Получение подписываемых данных](docs/STEP_30_PREPARE_CONTENT.md) мобильным приложением;\n6) Подписание данных;\n7) [Обработка подписанных данных](docs/STEP_40_PROCESS_CONTENT.md);\n8) [Проверка статуса подписания документа](docs/STEP_50_CHECK_DOCUMENT.md).\n\n#### События\n\nВ пакете реализованы следующие события:\n\n- `Mitwork\\Kalkan\\Events\\AuthAccepted` - аутентификация при запросе данных мобильным приложением подтверждена;\n- `Mitwork\\Kalkan\\Events\\AuthRejected` - аутентификация при запросе данных мобильным приложением не подтверждена;\n- `Mitwork\\Kalkan\\Events\\DocumentRejected` - документ отклонен;\n- `Mitwork\\Kalkan\\Events\\DocumentRequested` - документ запрошен;\n- `Mitwork\\Kalkan\\Events\\DocumentSaved` - документ сохранен;\n- `Mitwork\\Kalkan\\Events\\DocumentValidated` - подпись документа проверена;\n- `Mitwork\\Kalkan\\Events\\DocumentSigned` - документ подписан;\n- `Mitwork\\Kalkan\\Events\\RequestProcessed` - запрос обработан;\n- `Mitwork\\Kalkan\\Events\\RequestRejected` - запрос отклонен;\n- `Mitwork\\Kalkan\\Events\\RequestRequested` - сервисные данные запрошены;\n- `Mitwork\\Kalkan\\Events\\RequestSaved` - сервисные данные сохранены.\n\nДля подписки на любое из событий, в приложении можно реализовать собственный `EventListener`:\n\n```php\n\u003c?php\n\nnamespace App\\Listeners;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\Log;\nuse Mitwork\\Kalkan\\Events\\DocumentSigned;\n\nclass DocumentEventsListener\n{\n    /**\n     * Create the event listener.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    public function onSigned(DocumentSigned $event): void\n    {\n        Log::info('Документ подписан', [\n            'id' =\u003e $event-\u003eid,\n            'result' =\u003e $event-\u003eresult,\n        ]);\n    }\n}\n\n```\n\n## Ограничения\n\n### Работа с несколькими файлами\n\n~~При реализации подписания нескольких документов с использованием NCALayer, имеется возможность подписания только XML-документов.\nAPI не позволяет подписывать несколько файлов (хэшей) за один раз.~~\n\nВ текущей версии NCALayer данное ограничение [снято](https://github.com/pkigovkz/NCALayerJSExample/commit/7988e0780435fcadf93a8490fe7815ab1e4b3f1a#diff-637e566aaa8a12b82db96370dd3eea6bb066191a42c8891fb40bd495626b87d4R56).\n\n## Тестирование\n\nДля запуска тестов необходимо выполнить команду:\n\n```shell\n./vendor/bin/phpunit tests\n```\n\n**Важно** - в тестах используются тестовые сертификаты из [SDK](https://pki.gov.kz/get-sdk/) НУЦ РК, для проверки необходимо запустить NCANode со следующими параметрами:\n\n```shell\nNCANODE_DEBUG=true NCANODE_CRL_URL=\"http://test.pki.gov.kz/crl/nca_rsa_test.crl http://test.pki.gov.kz/crl/nca_gost_test.crl http://test.pki.gov.kz/crl/nca_gost2022_test.crl\" NCANODE_CRL_DELTA_URL=\"http://test.pki.gov.kz/crl/nca_d_rsa_test.crl http://test.pki.gov.kz/crl/nca_d_gost_test.crl http://test.pki.gov.kz/crl/nca_gost2022_d_test.crl\" NCANODE_CA_URL=\"http://test.pki.gov.kz/cert/root_gost_test.cer http://test.pki.gov.kz/cert/root_rsa_test.cer http://test.pki.gov.kz/cert/root_test_gost_2022.cer http://test.pki.gov.kz/cert/nca_gost_test.cer http://test.pki.gov.kz/cert/nca_rsa_test.cer http://test.pki.gov.kz/cert/nca_gost2022_test.cer\" NCANODE_OCSP_URL=http://test.pki.gov.kz/ocsp/ NCANODE_TSP_URL=http://test.pki.gov.kz/tsp/ java -jar NCANode-3.3.2.jar\n```\n\nДля работы с действительными сертификатами НУЦ РК, при тестировании приложение NCANode нужно запустить с параметрами по-умолчанию:\n\n```shell\njava -jar NCANode-3.3.2.jar\n```\n\n## Отказ от ответственности\n\nДанный пакет предоставляется и распространяется \"как есть\", автор (авторы) не несут юридической ответственности, которая может возникнуть\nпри использовании данного пакета или его отдельных частей.\n\nПри реализации приложений, использующих данный пакет, необходимо придерживаться законов и нормативных актов, регламентирующих работу\nс электронной цифровой подписью и электронным документом, в том числе:\n\n1) [Закон Республики Казахстан от 7 января 2003 года N 370 \"Об электронном документе и электронной цифровой подписи\"](https://adilet.zan.kz/rus/docs/Z030000370_);\n2) [Приказ Министра по инвестициям и развитию Республики Казахстан от 9 декабря 2015 года № 1187 Об утверждении Правил проверки подлинности электронной цифровой подписи](https://adilet.zan.kz/rus/docs/V1500012864).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitwork%2Fkalkan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitwork%2Fkalkan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitwork%2Fkalkan/lists"}