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 for PHP
Standalone PDF digital-signature library for PHP — PAdES / CMS signing with no external services.
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.”
![]() 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-i686Windows 7 → 11, 64 / 32-bit windows-aarch64Windows on ARM64 linux-x86_64/linux-aarch64/linux-arm/linux-i686Linux x64 / ARM64 / ARM / 32-bit (glibc 2.17+, every distro) darwin-x86_64/darwin-aarch64macOS 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
- 点击次数: 4
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: AGPL-3.0-or-later
- 更新时间: 2026-06-15



