mitwork / kalkan
签名,使用kalkan进行数字签名验证(NCALayer,NCANode)
Requires
- php: ^8.2|^8.3
- ext-dom: *
- ext-gd: *
- ext-json: *
- ext-libxml: *
- endroid/qr-code: ^5.0
- guzzlehttp/guzzle: ^7.8
- illuminate/events: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- khanamiryan/qrcode-detector-decoder: ^2.0
- laravel/pint: ^1.13
- orchestra/testbench: ^8.13|^9.2.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.4
- symfony/yaml: ^6.3|^7.0
README
该库实现了以下功能
- 签名XML数据;
- 签名二进制数据(CMS);
- 验证和提取签名数据;
- 二维码,交叉签名。
外部依赖
- NCALayer - 在浏览器端进行客户端数据签名;
- NCANode - 验证、验证和提取签名数据;
- eGov mobile (App Store, PlayMarket), eGov business (App Store, PlayMarket) - 二维码和交叉签名。
为了实现二维码和交叉签名,您的信息系统必须连接到通过Egov Mobile应用程序进行二维码签名服务,并且必须在运营商端添加外部地址(地址)。
在测试阶段,可能需要安装eGov mobile和eGov business的测试版应用程序 - 直接为Android操作系统,或者通过运营商服务链接的TestFlight进行。为了测试交叉链接,还需要指定带有测试应用程序标识符的正确链接。
支持的版本
- PHP - 8.2, 8.3;
- Laravel - 10, 11。
安装
此包通过composer在现有或新Laravel项目中安装,命令为
composer require mitwork/kalkan
配置
要添加更改,需要使用命令发布项目的配置
php artisan vendor:publish --tag kalkan-config
参数在config/kalkan.php文件中设置和/或重定义
<?php return [ 'ncanode' => [ 'host' => env('NCANODE_HOST', 'https://:14579'), ], 'links' => [ 'prefix' => 'mobileSign:', 'mobile' => 'https://mgovsign.page.link/?link=%s&isi=1476128386&ibi=kz.egov.mobile&apn=kz.mobile.mgov', 'business' => 'https://egovbusiness.page.link/?link=%s&isi=1597880144&ibi=kz.mobile.mgov.business&apn=kz.mobile.mgov.business', ], 'actions' => [ 'store-document' => 'store-document', 'store-request' => 'store-request', 'generate-qr-code' => 'generate-qr-code', 'generate-cross-link' => 'generate-cross-link', 'generate-service-link' => 'generate-service-link', 'prepare-content' => 'prepare-content', 'process-content' => 'process-content', 'check-document' => 'check-document', 'check-request' => 'check-request', ], 'options' => [ 'description' => 'Текст для пользователя', 'organisation' => [ 'nameRu' => 'АО ТЕСТ', 'nameKz' => 'ТЕСТ АҚ', 'nameEn' => 'JS TEST', 'bin' => '123456789012', ], 'auth' => [ 'type' => 'None', // Bearer 'token' => '', ], ], 'ttl' => 180, ];
其中
ncanode.host- 连接到NCANode的地址和端口;links.prefix- 用于生成QR-code链接的前缀;links.mobile- 在eGov mobile应用程序中签名时生成交叉链接的模板;links.business- 在eGov business应用程序中签名时生成交叉链接的模板;actions- 用于QR和交叉签名时与应用程序交互的命名路由;options.description- 请求名称或信息系统名称;options.organisation- 组织信息;auth.type- 生成QR签名服务链接时的授权类型,允许的值 -None,Bearer;auth.token- 授权令牌,如果未指定请求,则将生成唯一的单次使用令牌;ttl- 单次使用链接的有效时间(秒)。
使用
签名和验证XML数据
此签名示例适用于在后台签名,当数字证书密钥位于服务器上时。为了验证通过NCALayer签名的数据,必须通过HTTP请求传递签名数据。
<?php namespace App\Controllers; use \Mitwork\Kalkan\Services\KalkanSignatureService; use \Mitwork\Kalkan\Services\KalkanValidationService; class TestXmlController extends Controller { function __construct( public KalkanSignatureService $signatureService, public KalkanValidationService $validationService, ) { // } function testXmlSign(): string { $xml = '<?xml...'; $key = 'base64...'; $password = 'password'; $result = $this->signatureService->signXml($xml, $key, $password); // dd($result); // <?xml... return $result; } function testXmlVerify(): bool { $signedXml = $this->testXmlSign(); $result = $this->validationService->verifyXml($signedXml); // dd($result); // true return $result; } }
签名、验证和提取CMS数据
此签名示例适用于在后台签名,当数字证书密钥位于服务器上时。为了验证通过NCALayer签名的数据,必须通过HTTP请求传递签名数据。
<?php namespace App\Controllers; use \Mitwork\Kalkan\Services\KalkanSignatureService; use \Mitwork\Kalkan\Services\KalkanValidationService; use \Mitwork\Kalkan\Services\KalkanExtractionService; class TestCmsController extends Controller { function __construct( public KalkanSignatureService $signatureService, public KalkanValidationService $validationService, public KalkanExtractionService $extractionService, ) { // } function testCmsSign(): string { $data = 'base64...'; $key = 'base64...'; $password = 'password'; $result = $this->signatureService->signCms($data, $key, $password); // dd($result); // base64... return $result; } function testCmsVerify(): bool { $cms = 'base64...'; $data = 'base64...'; $result = $this->validationService->verifyCms($cms, $data); // dd($result); // true return $result; } function testCmsExtract(): string { $cms = 'base64...'; $result = $this->extractionService->extractCms($cms); // dd($result); // base64... return $result; } }
二维码、交叉签名
由于交互是通过HTTP协议进行的,因此该包除了包含服务外,还包含执行所有必要步骤的预定义Http\Actions。
POST/api/documents- 上传文档;POST/api/requests- 生成请求;GET/api/requests/generate/{id}- 生成服务链接;GET/api/requests/qr-code/{id}- 生成二维码;GET/api/requests/links/{id}- 生成交叉链接;GET/api/requests/{id}- 数据处理 - 输出;PUT/api/requests/{id}- 数据处理 - 处理;GET/check/document/{id}- 检查文档签署状态;GET/check/request/{id}- 检查申请状态。
要使用预定义方法,需要在 routes/api.php 中指定路由,这些路由在单独的文档或源代码中描述。
如有需要,可以指定自定义处理程序来覆盖任何步骤。每个步骤的详细信息在下面的章节中介绍。
二维码签署
该机制允许使用智能手机通过 eGov mobile 或 eGov business 应用程序签署数据,当项目在电脑或平板电脑的浏览器中打开时。
主要步骤
- 上传文档 - 此步骤是可选的,可以在第 2 步发送文档;
- 创建请求和生成服务链接;
- 生成二维码;
- 使用移动应用程序扫描二维码;
- 获取待签署数据移动应用程序;
- 签署数据;
- 处理签署数据;
- 检查文档签署状态.
交叉签署
该机制允许使用智能手机通过 eGov Mobile 或 eGov Business 应用程序签署数据,当项目(网站)在智能手机上打开时。
主要步骤
- 上传文档 - 此步骤是可选的,可以在第 2 步发送文档;
- 创建请求和生成服务链接;
- 生成交叉链接;
- 在移动应用程序中点击交叉链接;
- 获取待签署数据移动应用程序;
- 签署数据;
- 处理签署数据;
- 检查文档签署状态.
事件
该包实现了以下事件
Mitwork\Kalkan\Events\AuthAccepted- 移动应用程序请求数据时的身份验证已确认;Mitwork\Kalkan\Events\AuthRejected- 移动应用程序请求数据时的身份验证未确认;Mitwork\Kalkan\Events\DocumentRejected- 文档被拒绝;Mitwork\Kalkan\Events\DocumentRequested- 文档被请求;Mitwork\Kalkan\Events\DocumentSaved- 文档已保存;Mitwork\Kalkan\Events\DocumentValidated- 文档签名已验证;Mitwork\Kalkan\Events\DocumentSigned- 文档已签署;Mitwork\Kalkan\Events\RequestProcessed- 请求已处理;Mitwork\Kalkan\Events\RequestRejected- 请求被拒绝;Mitwork\Kalkan\Events\RequestRequested- 请求服务数据;Mitwork\Kalkan\Events\RequestSaved- 服务数据已保存。
要订阅任何事件,可以在应用程序中实现自定义 EventListener。
<?php namespace App\Listeners; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Facades\Log; use Mitwork\Kalkan\Events\DocumentSigned; class DocumentEventsListener { /** * Create the event listener. */ public function __construct() { // } public function onSigned(DocumentSigned $event): void { Log::info('Документ подписан', [ 'id' => $event->id, 'result' => $event->result, ]); } }
限制
处理多个文件
在通过 NCALayer 实现多个文档签署时,只能签署 XML 文档。API 不允许一次签署多个文件(哈希值)。
解决方案选项
- 在服务器上通过选择电子签名证书和请求密码进行签署 - 不安全 且不适用于与令牌(KazToken、JaCarta)一起工作;
- 在服务器上生成并客户端签署待签署文档的存档;
- 通过二维码或交叉链接以其他方式签署。
测试
要运行测试,需要执行以下命令
./vendor/bin/phpunit tests
重要 - 测试使用的是来自 SDK 的测试证书,为了验证,需要使用以下参数启动 NCANode
NCANODE_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_gost_test_2022.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_d_gost_test_2022.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.2.3.jar
要使用有效的哈萨克斯坦国家认证中心证书进行工作,在测试时需要使用默认参数启动 NCANode 应用程序
java -jar NCANode-3.2.3.jar
免责声明
本包提供和分发“按原样”,作者(作者)不对使用本包或其任何部分可能产生的任何法律责任负责。
在实施使用本软件包的应用程序时,必须遵守有关电子数字签名和电子文件操作的法律和法规,包括