aniketc068/atick 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

aniketc068/atick

Composer 安装命令:

composer require aniketc068/atick

包简介

Standalone PDF digital-signature library for PHP — PAdES & CMS signing with a PFX/PEM file, USB tokens (PKCS#11), the Windows certificate store and Indian eSign (CCA); RFC-3161 timestamps, long-term validation (LTV) and a green-tick verified-signature appearance that Adobe shows as valid. Zero depen

README 文档

README

ATick

ATick for PHP

Standalone PDF digital-signature library for PHP — PAdES / CMS signing with no external services.

Packagist PHP PAdES Cross-platform License: AGPL v3 Also for Python Also for Java Also for .NET Also for Node.js

Also available in other languages — the same ATick engine, the same API, native to each ecosystem:

Language Install Source · Docs
Python pip install atick ATick-Python · docs
Java io.github.aniketc068:atick (Maven) ATick-Java · docs
.NET dotnet add package ATick ATick-DotNet · docs
Node.js npm install atick ATick-Node · docs

ATick signs PDFs the way Adobe Acrobat and the EU DSS do — PAdES baseline signatures with timestamps and long-term validation. The matching engine for your platform ships inside the package and is loaded automatically through PHP FFI — there is no external service, nothing to compile, and no PHP dependencies. Run composer require aniketc068/atick and you are done.

<?php
require 'vendor/autoload.php';

use Aniketc068\ATick\Atick;

$signed = Atick::signPfx(
    file_get_contents('doc.pdf'),
    file_get_contents('my.pfx'),
    [
        'password'   => '••••',
        'cn'         => 'Aniket Chaturvedi',
        'reason'     => 'Approved',
        'green_tick' => true,
        'page'       => 1,
        'rect'       => [300, 55, 575, 175],
        'pades'      => true, 'timestamp' => true, 'ltv' => true,   // PAdES-B-LT
    ]
);

file_put_contents('signed.pdf', $signed);

Options are a plain PHP array (shown above) — or a JSON string if you prefer. Buffers (PDF / PFX / output) are PHP binary strings. Any failure throws an Aniketc068\ATick\AtickException.

Runs anywhere PHP runs — Laravel, Symfony, WordPress, plain PHP, CLI scripts, queue workers. It uses FFI, so the FFI extension must be enabled (see Requirements).

The green tick your readers trust

ATick draws a verified-signature appearance with a green tick. When the certificate is valid and trusted, Adobe Reader / Acrobat shows “Signed and all signatures are valid.”

Adobe — signed and all signatures are valid

Valid & trusted
green tick

Validity unknown
yellow “?”

Not verified
“?” not validated

Invalid
red cross

Install

composer require aniketc068/atick

The engine for your platform comes with the package. There is no build step and no extra download.

Requirements

  • PHP 7.4 or newer with the FFI extension enabled.
    • On the CLI SAPI, FFI is usually available out of the box.

    • On web SAPIs (PHP-FPM / Apache) set in php.ini:

      extension=ffi
      ffi.enable=1          ; or: ffi.enable=preload  (then set opcache.preload)
  • No other PHP extension is required — the cryptography, PKCS#12 / PEM, PKCS#11, image decoding, timestamping and LTV are all built into the bundled engine.

Features (A → Z)

Feature How
Sign with a .pfx / .p12 / .pem Atick::signPfx($pdf, $pfx, $options) — PKCS#12 or PEM (key + certs), auto-detected
PAdES levels B-B / B-T / B-LT / B-LTA 'pades' => true + 'timestamp' => true + 'ltv' => true + 'lta' => true
Hash algorithm 'hash_algo' => 'sha256' | 'sha384' | 'sha512'
Timestamp authority built in — or your own with 'tsa_url' => '…' (and 'tsa_auth' => ['user','pass'])
Long-term validation (LTV) 'ltv' => true embeds the chain + revocation (CRL/OCSP)
Multi-page / custom coordinates 'placements' => [[page, [x1,y1,x2,y2]], …]
Signature layout 'mode' => 'single' (one signature on many pages) · 'mode' => 'shared' (many fields, same value)
Multi-signatory sign an already-signed PDF again — each signature is its own revision, all stay valid
Certification (DocMDP) 'certify' => 1 (no changes) · 2 (form filling) · 3 (form filling + annotations)
Field locking (FieldMDP) 'lock_fields' => ['*'] or ['FieldA', …]
Pre-sign checks 'verify_expiry' => true, 'verify_crl' => true, 'verify_ocsp' => true (or 'verify' => true)
Document metadata Atick::setMetadata($pdf, $options)
Password protection 'encrypt_password' (+ 'owner_password') for output; 'open_password' for input; Atick::decrypt($pdf, $pw)
Appearance options cn, org, ou, location, reason, text, date, dn, body, heading, image — auto-fit text, transparent logo
The mark the ? (Adobe greens it), an always-green tick, or nothing — see The mark
CN on the left (Adobe-style) 'image' => 'cn'
Distinguished name 'dn' => 'CN=…, O=…, C=IN'
Custom-text-only appearance 'body' => "*APPROVED*\nby *Aniket*"\n = line, *x* = bold
Invisible signature 'placements' => []
Sign an already-signed PDF sign again (incremental) — existing signatures stay valid; use a fresh 'field_name'
Container only Atick::prepareFields($pdf, $options)
Document timestamp 'lta' => true while signing; Atick::addDocTimestamp($pdf, $options) afterwards (PAdES-B-LTA)
Fast signing revocation cache (ON by default) — Atick::setFastSigning(false) to disable
Deferred / eSign (2-step) Atick::prepare($pdf, $options) → external CMS → Atick::embed($prepared, $cms)
Detached CMS Atick::cmsPfx($data, $pfx, $options)

The API

Atick::signPfx($pdf, $pfx, $options);        // sign with a .pfx / .p12 / .pem (auto-detected)
Atick::prepare($pdf, $options);              // deferred / eSign: returns [$prepared, $bytesToSign]
Atick::cmsPfx($data, $pfx, $options);        // detached CMS over data
Atick::embed($prepared, $cms);               // embed a detached CMS into a prepared PDF
Atick::prepareFields($pdf, $options);        // make an empty signature field (template)
Atick::signField($pdf, $pfx, $options);      // sign an existing empty field
Atick::setMetadata($pdf, $options);          // Title / Author / Subject / Keywords / …
Atick::addDocTimestamp($pdf, $options);      // archive DocTimeStamp (PAdES-B-LTA)
Atick::setFastSigning(true | false);         // revocation-cache toggle
Atick::decrypt($pdf, $password);             // decrypt a password-protected PDF
Atick::version();                            // engine version

Every method is static. $options is a PHP array (recommended) or a JSON string. All buffers are PHP binary strings. Any failure throws Aniketc068\ATick\AtickException whose getMessage() is the reason.

Options

cn, org, ou, location, reason, text, date, dn, body, heading, show_mark, green_tick, always_check, mark_color (hex / name / [r,g,b]), mark_gradient, mark_scale, text_color, bg_color, border, font_size, width, height, page, rect, placements ([[page,[x1,y1,x2,y2]], …]), mode (single/shared), field_name, pades, hash_algo (sha256/384/512), timestamp, tsa_url, tsa_auth, ltv, lta, certify, lock_fields, verify, verify_expiry, verify_crl, verify_ocsp, open_password, encrypt_password, owner_password, contents_size.

The mark

['green_tick' => true]      // the "?" mark — Adobe paints it GREEN for valid+trusted, RED if invalid
['always_check' => true]    // the green-tick graphic as the base
['green_tick' => false]     // no mark — a plain signature

Colour it: 'mark_color' => '#E53935', 'blue', [255,140,0] — or a gradient 'mark_gradient' => ['red','orange','yellow'].

Deferred signing & Indian eSign (two-step)

When the private key lives elsewhere (a token / HSM / smart-card, or an eSign ESP):

[$prepared, $bytesToSign] = Atick::prepare($pdf, [
    'cn' => 'DS TEST', 'reason' => 'eSign',
    'placements' => [[1, [300, 55, 575, 175]]], 'contents_size' => 16384,
]);

// the eSign InputHash is the SHA-256 of $bytesToSign:
$inputHash = hash('sha256', $bytesToSign);
// ... sign with your provider / eSign ESP, get back a detached CMS ...

$signed = Atick::embed($prepared, $cms);

PAdES levels

Atick::signPfx($pdf, $pfx, ['pades' => true]);                                            // B-B
Atick::signPfx($pdf, $pfx, ['pades' => true, 'timestamp' => true]);                       // B-T
Atick::signPfx($pdf, $pfx, ['pades' => true, 'timestamp' => true, 'ltv' => true]);        // B-LT
Atick::signPfx($pdf, $pfx, ['pades' => true, 'timestamp' => true, 'lta' => true]);        // B-LTA

Compatibility — one package everywhere

  • PHP 7.4 → the latest 8.x — FFI is part of every supported PHP version.

  • Every OS/arch — the matching engine ships for each platform and is selected automatically:

    OS · arch Covers
    windows-x86_64 / windows-i686 Windows 7 → 11, 64 / 32-bit
    windows-aarch64 Windows on ARM64
    linux-x86_64 / linux-aarch64 / linux-arm / linux-i686 Linux x64 / ARM64 / ARM / 32-bit (glibc 2.17+, every distro)
    darwin-x86_64 / darwin-aarch64 macOS Intel / Apple Silicon

Errors

use Aniketc068\ATick\AtickException;

try {
    Atick::signPfx($pdf, $pfx, ['password' => 'wrong']);
} catch (AtickException $e) {
    error_log('signing failed: ' . $e->getMessage());
}

License

ATick is dual-licensed — free for personal & open use, paid if you sell:

  • Free under GNU AGPL-3.0 — personal projects, learning, internal use, and open-source projects (released publicly under AGPL-3.0).
  • Commercial license (paid) — if you build a product with ATick and sell it, or use it in a closed-source / commercial product, you must buy a commercial license first. Contact aniketc.pro@gmail.com for a quote.

See LICENSING.md for details. © 2026 Aniket Chaturvedi.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: AGPL-3.0-or-later
  • 更新时间: 2026-06-15

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固