setasign/seta-pdf-signer-addon-global-sign-dss

SetaPDF-Signer 组件的签名模块,用于 GlobalSign 数字签名服务。

v2.0.0 2021-12-10 10:33 UTC

This package is auto-updated.

Last update: 2024-09-20 00:46:22 UTC


README

本软件包为 SetaPDF-Signer 组件提供模块,允许您使用 基于云的数字签名服务(由 GlobalSign 提供)在纯 PHP 中对 PDF 文档进行数字签名和加时间戳。

要求

要使用此软件包,您需要 GlobalSign 数字签名服务的凭证,包括

  1. 您的私钥
  2. 用于 API 的 mTLS 连接的客户端证书
  3. 您的 API 密钥和密码

有关详细信息,请参阅 "GlobalSign-Digital-Signing-Service-Guide 1.3.pdf"(或更新的版本)。请联系 GlobalSign 获取此文件。

本软件包在 PHP >= 7.1 上开发和测试。有关 SetaPDF-Signer 组件的要求,请参阅此处

我们使用 PSR-17 (HTTP Factories)PSR-18 (HTTP Client) 进行请求。因此,您需要一个这些的实现。我们推荐使用 Guzzle。

对于 PHP 7.1

    "require" : {
        "guzzlehttp/guzzle": "^6.5",
        "http-interop/http-factory-guzzle": "^1.0",
        "mjelamanov/psr18-guzzle": "^1.3"
    }

对于 >= PHP 7.2

    "require" : {
        "guzzlehttp/guzzle": "^7.0",
        "http-interop/http-factory-guzzle": "^1.0"
    }

安装

将以下内容添加到您的 composer.json 中

{
    "require": {
        "setasign/seta-pdf-signer-addon-global-sign-dss": "^2.0"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://www.setasign.com/downloads/"
        }
    ]
}

然后执行 composer update。您需要定义 repository 以评估对 SetaPDF-Signer 组件的依赖关系(有关更多详细信息,请参阅此处)。

评估版本

默认情况下,此软件包依赖于 SetaPDF-Signer 组件的授权版本。如果想要使用评估版本,请在 composer.json 中使用以下内容

{
    "require": {
        "setasign/seta-pdf-signer-addon-global-sign-dss": "dev-evaluation"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://www.setasign.com/downloads/"
        }
    ]
}

用法

本软件包中的所有类都位于命名空间 setasign\SetaPDF\Signer\Module\GlobalSign\Dss 中。

Client 类

存在一个简单的 Client 类,它将 REST API 包装成简单的 PHP 方法。它内部处理身份验证、请求和响应。

此类的构造函数需要以下参数

  • $httpClient PSR-18 HTTP 客户端实现。
  • $requestFactory PSR-17 HTTP 工厂实现。
  • $streamFactory PSR-17 HTTP 工厂实现。
  • $apiKey 是您从 GlobalSign 收到的 API 密钥。
  • $apiSecret 是您 API 密钥的密钥,也是您从 GlobalSign 收到的。

一个常见的创建方式如下

$options = [
    'http_errors' => false, // recommended for guzzle - because of PSR-18
    'cert' => 'path/to/tls-cert.pem',
    'ssl_key' => 'path/to/private/key.pem'  
];

$apiKey = 'xxxxxxxxxxxxxxxx';
$apiSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$httpClient = new GuzzleHttp\Client($options);
// if you are using php 7.0 or 7.1
//$httpClient = new Mjelamanov\GuzzlePsr18\Client($httpClient);
$requestFactory = new Http\Factory\Guzzle\RequestFactory();
$streamFactory = new Http\Factory\Guzzle\StreamFactory();

$client = new Dss\Client($httpClient, $requestFactory, $streamFactory, $apiKey, $apiSecret);

您可以使用此实例进行查询等操作

$remainingSignatures = $client->getQuota(Dss\Client::TYPE_SIGNATURES);
// or 
$signaturesCount = $client->getCount(Dss\Client::TYPE_SIGNATURES);

要创建数字签名,您需要首先创建一个签名证书,可以使用 getIdentity() 方法完成。此方法的参数可以是一个关联数组,如 此处 所定义。该方法将返回一个 Identity 实例,它只是返回的 id、签名证书和 OCSP 响应的数据包装器。

$identity = $client->getIdentity();

Identity 需要转发到签名模块,该模块内部将其传递回 Dss\Client\sign() 方法以获取最终签名。也可以单独使用此方法(仅为完整性考虑)

$signature = $client->sign($identity, hash('sha256', $data));

SignatureModule

这是主签名模块,可与 SetaPDF-Signer 组件一起使用。其构造函数需要以下参数

  • $signer 是传递给模块的 \SetaPDF_Signer 类的实例。内部调用 $signer->setAllowSignatureContentLengthChange(false) 来禁止重复的签名请求。
  • $client 需要是 Dss\Client 实例。
  • $identityDss\Identity 实例。
  • $module 需要是一个 CMSPAdES 签名模块实例。它用于内部创建 CMS 容器。

一个简单的完整签名过程如下所示

// set up the client and identity
$options = [
    'http_errors' => false,
    'cert' => 'path/to/tls-cert.pem',
    'ssl_key' => 'path/to/private/key.pem'  
];

$apiKey = 'xxxxxxxxxxxxxxxx';
$apiSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$httpClient = new GuzzleHttp\Client($options);
// if you are using php 7.0 or 7.1
//$httpClient = new Mjelamanov\GuzzlePsr18\Client($httpClient);
$requestFactory = new Http\Factory\Guzzle\RequestFactory();
$streamFactory = new Http\Factory\Guzzle\StreamFactory();

$client = new Dss\Client($httpClient, $requestFactory, $streamFactory, $apiKey, $apiSecret);
$identity = $client->getIdentity();

// now start the signature process
$writer = new \SetaPDF_Core_Writer_File('signed.pdf');
$document = \SetaPDF_Core_Document::loadByFilename('invoice.pdf', $writer);
 
$signer = new \SetaPDF_Signer($document);
$signer->setSignatureContentLength(15000);

$pades = new \SetaPDF_Signer_Signature_Module_Pades();
$module = new Dss\SignatureModule($signer, $client, $identity, $pades);
 
$signer->sign($module);

TimestampModule

此模块可用于向数字签名添加时间戳或创建文档级别的时间戳。其构造函数只需一个 Dss\Client 实例

$tsmodule = new Dss\TimestampModule($client);

它不需要像签名模块一样传递身份,但可以传递给 \SetaPDF_Signer 实例

$signer->setTimestampModule($tsmodule);
// ...
$signer->sign($module);

或者您可以用它创建文档级别的时间戳

$signer->setTimestampModule($tsmodule);
// ...
$signer->timestamp();

关于测试的信息

测试套件目前仅包含功能测试,这些测试会调用 真实服务调用!请记住,这些调用会从您的签名配额中扣除。您不应该在自动化的环境中执行这些测试!!!

要执行测试,您需要在包的根目录中创建一个文件夹,并包含以下文件

/private/
    credentials.php

credentials.php 文件需要返回您的凭据、证书和私钥

<?php
        
return [
    'apiKey' => '<YOUR API KEY>',
    'apiSecret' => '<YOUR API SECRET>',
    'cert' => '/path/to/your/mTLS/certificate.pem',
    'privateKey' => '/path/to/your/private/key.pem'
];

许可

此包是开源软件,受 MIT 许可 许可。