{"id":50908208,"url":"https://github.com/aniketc068/atick-php","last_synced_at":"2026-06-22T13:00:55.161Z","repository":{"id":365165852,"uuid":"1270860912","full_name":"Aniketc068/ATick-PHP","owner":"Aniketc068","description":"Standalone PDF digital-signature library for PHP — PAdES/CMS signing (PFX/PEM, deferred eSign/HSM/token), RFC-3161 timestamps, LTV, green-tick appearance. Engine bundled via PHP FFI, cross-platform, composer require.","archived":false,"fork":false,"pushed_at":"2026-06-16T10:38:17.000Z","size":22025,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T08:26:50.212Z","etag":null,"topics":["composer","digital-signature","esign","packagist","pades","pdf","pdf-signature","php"],"latest_commit_sha":null,"homepage":"https://atick.readthedocs.io/docs/php/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aniketc068.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-16T05:45:32.000Z","updated_at":"2026-06-16T10:39:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Aniketc068/ATick-PHP","commit_stats":null,"previous_names":["aniketc068/atick-php"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Aniketc068/ATick-PHP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-PHP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-PHP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-PHP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-PHP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aniketc068","download_url":"https://codeload.github.com/Aniketc068/ATick-PHP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aniketc068%2FATick-PHP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34483282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["composer","digital-signature","esign","packagist","pades","pdf","pdf-signature","php"],"created_at":"2026-06-16T07:04:11.541Z","updated_at":"2026-06-18T09:00:47.564Z","avatar_url":"https://github.com/Aniketc068.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/atick_logo.png\" alt=\"ATick\" width=\"260\"/\u003e\n\n# ATick for PHP\n\n**Standalone PDF digital-signature library for PHP — PAdES / CMS signing with no external services.**\n\n[![Packagist](https://img.shields.io/packagist/v/aniketc068/atick?color=2ea44f\u0026label=packagist)](https://packagist.org/packages/aniketc068/atick)\n[![PHP](https://img.shields.io/badge/php-7.4%2B-777BB4?logo=php\u0026logoColor=white)](https://www.php.net/)\n[![PAdES](https://img.shields.io/badge/PAdES-B--B%20%7C%20B--T%20%7C%20B--LT%20%7C%20B--LTA-success)](#pades-levels)\n[![Cross-platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-brightgreen)](#compatibility--one-package-everywhere)\n[![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)\n[![Also for Python](https://img.shields.io/badge/also%20for-Python-3776AB?logo=python\u0026logoColor=white)](https://github.com/Aniketc068/ATick-Python)\n[![Also for Java](https://img.shields.io/badge/also%20for-Java-007396?logo=openjdk\u0026logoColor=white)](https://github.com/Aniketc068/ATick-Java)\n[![Also for .NET](https://img.shields.io/badge/also%20for-.NET-512BD4?logo=dotnet\u0026logoColor=white)](https://github.com/Aniketc068/ATick-DotNet)\n[![Also for Node.js](https://img.shields.io/badge/also%20for-Node.js-339933?logo=node.js\u0026logoColor=white)](https://github.com/Aniketc068/ATick-Node)\n\n\u003c/div\u003e\n\n**Also available in other languages** — the same ATick engine, the same API, native to each ecosystem:\n\n| Language | Install | Source · Docs |\n|---|---|---|\n| **Python** | `pip install atick` | [ATick-Python](https://github.com/Aniketc068/ATick-Python) · [docs](https://atick.readthedocs.io/) |\n| **Java** | `io.github.aniketc068:atick` (Maven) | [ATick-Java](https://github.com/Aniketc068/ATick-Java) · [docs](https://atick-java.readthedocs.io/) |\n| **.NET** | `dotnet add package ATick` | [ATick-DotNet](https://github.com/Aniketc068/ATick-DotNet) · [docs](https://atick-dotnet.readthedocs.io/) |\n| **Node.js** | `npm install atick` | [ATick-Node](https://github.com/Aniketc068/ATick-Node) · [docs](https://atick-node.readthedocs.io/) |\n\n---\n\nATick signs PDFs the way Adobe Acrobat and the EU DSS do — **PAdES baseline** signatures with\ntimestamps and long-term validation. The matching engine for your platform ships **inside the\npackage** and is loaded automatically through PHP **FFI** — there is **no external service**,\n**nothing to compile**, and **no PHP dependencies**. Run `composer require aniketc068/atick` and\nyou are done.\n\n```php\n\u003c?php\nrequire 'vendor/autoload.php';\n\nuse Aniketc068\\ATick\\Atick;\n\n$signed = Atick::signPfx(\n    file_get_contents('doc.pdf'),\n    file_get_contents('my.pfx'),\n    [\n        'password'   =\u003e '••••',\n        'cn'         =\u003e 'Aniket Chaturvedi',\n        'reason'     =\u003e 'Approved',\n        'green_tick' =\u003e true,\n        'page'       =\u003e 1,\n        'rect'       =\u003e [300, 55, 575, 175],\n        'pades'      =\u003e true, 'timestamp' =\u003e true, 'ltv' =\u003e true,   // PAdES-B-LT\n    ]\n);\n\nfile_put_contents('signed.pdf', $signed);\n```\n\n\u003e **Options** are a plain PHP array (shown above) — or a JSON **string** if you prefer. **Buffers**\n\u003e (PDF / PFX / output) are PHP binary strings. Any failure throws an `Aniketc068\\ATick\\AtickException`.\n\n\u003e **Runs anywhere PHP runs** — Laravel, Symfony, WordPress, plain PHP, CLI scripts, queue workers.\n\u003e It uses FFI, so the FFI extension must be enabled (see [Requirements](#requirements)).\n\n---\n\n## The green tick your readers trust\n\nATick draws a verified-signature appearance with a green tick. When the certificate is valid and\ntrusted, Adobe Reader / Acrobat shows **“Signed and all signatures are valid.”**\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/valid_signature_adobe.png\" alt=\"Adobe — signed and all signatures are valid\" width=\"560\"/\u003e\n\u003c/div\u003e\n\n\u003ctable align=\"center\"\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/signature_appearance.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eValid \u0026amp; trusted\u003c/b\u003e\u003cbr/\u003egreen tick\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/sig_unknown.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eValidity unknown\u003c/b\u003e\u003cbr/\u003eyellow “?”\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/sig_notverified.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eNot verified\u003c/b\u003e\u003cbr/\u003e“?” not validated\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/Aniketc068/ATick-PHP/main/assets/sig_invalid.png\" width=\"190\"/\u003e\u003cbr/\u003e\u003cb\u003eInvalid\u003c/b\u003e\u003cbr/\u003ered cross\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Install\n\n```bash\ncomposer require aniketc068/atick\n```\n\nThe engine for your platform comes with the package. There is no build step and no extra download.\n\n## Requirements\n\n- **PHP 7.4 or newer** with the **FFI extension** enabled.\n  - On the **CLI** SAPI, FFI is usually available out of the box.\n  - On **web** SAPIs (PHP-FPM / Apache) set in `php.ini`:\n\n    ```ini\n    extension=ffi\n    ffi.enable=1          ; or: ffi.enable=preload  (then set opcache.preload)\n    ```\n- No other PHP extension is required — the cryptography, PKCS#12 / PEM, PKCS#11, image decoding,\n  timestamping and LTV are all built into the bundled engine.\n\n---\n\n## Features (A → Z)\n\n| Feature | How |\n|---|---|\n| **Sign with a `.pfx` / `.p12` / `.pem`** | `Atick::signPfx($pdf, $pfx, $options)` — PKCS#12 or PEM (key + certs), auto-detected |\n| **PAdES levels** B-B / B-T / B-LT / B-LTA | `'pades' =\u003e true` + `'timestamp' =\u003e true` + `'ltv' =\u003e true` + `'lta' =\u003e true` |\n| **Hash algorithm** | `'hash_algo' =\u003e 'sha256' \\| 'sha384' \\| 'sha512'` |\n| **Timestamp authority** | built in — or your own with `'tsa_url' =\u003e '…'` (and `'tsa_auth' =\u003e ['user','pass']`) |\n| **Long-term validation (LTV)** | `'ltv' =\u003e true` embeds the chain + revocation (CRL/OCSP) |\n| **Multi-page / custom coordinates** | `'placements' =\u003e [[page, [x1,y1,x2,y2]], …]` |\n| **Signature layout** | `'mode' =\u003e 'single'` (one signature on many pages) · `'mode' =\u003e 'shared'` (many fields, same value) |\n| **Multi-signatory** | sign an already-signed PDF again — each signature is its own revision, all stay valid |\n| **Certification (DocMDP)** | `'certify' =\u003e 1` (no changes) · `2` (form filling) · `3` (form filling + annotations) |\n| **Field locking (FieldMDP)** | `'lock_fields' =\u003e ['*']` or `['FieldA', …]` |\n| **Pre-sign checks** | `'verify_expiry' =\u003e true`, `'verify_crl' =\u003e true`, `'verify_ocsp' =\u003e true` (or `'verify' =\u003e true`) |\n| **Document metadata** | `Atick::setMetadata($pdf, $options)` |\n| **Password protection** | `'encrypt_password'` (+ `'owner_password'`) for output; `'open_password'` for input; `Atick::decrypt($pdf, $pw)` |\n| **Appearance** | options `cn, org, ou, location, reason, text, date, dn, body, heading, image` — auto-fit text, transparent logo |\n| **The mark** | the `?` (Adobe greens it), an always-green tick, or nothing — see [The mark](#the-mark) |\n| **CN on the left** (Adobe-style) | `'image' =\u003e 'cn'` |\n| **Distinguished name** | `'dn' =\u003e 'CN=…, O=…, C=IN'` |\n| **Custom-text-only appearance** | `'body' =\u003e \"*APPROVED*\\nby *Aniket*\"` — `\\n` = line, `*x*` = bold |\n| **Invisible signature** | `'placements' =\u003e []` |\n| **Sign an already-signed PDF** | sign again (incremental) — existing signatures stay valid; use a fresh `'field_name'` |\n| **Container only** | `Atick::prepareFields($pdf, $options)` |\n| **Document timestamp** | `'lta' =\u003e true` while signing; `Atick::addDocTimestamp($pdf, $options)` afterwards (PAdES-B-LTA) |\n| **Fast signing** | revocation cache (ON by default) — `Atick::setFastSigning(false)` to disable |\n| **Deferred / eSign (2-step)** | `Atick::prepare($pdf, $options)` → external CMS → `Atick::embed($prepared, $cms)` |\n| **Detached CMS** | `Atick::cmsPfx($data, $pfx, $options)` |\n\n---\n\n## The API\n\n```php\nAtick::signPfx($pdf, $pfx, $options);        // sign with a .pfx / .p12 / .pem (auto-detected)\nAtick::prepare($pdf, $options);              // deferred / eSign: returns [$prepared, $bytesToSign]\nAtick::cmsPfx($data, $pfx, $options);        // detached CMS over data\nAtick::embed($prepared, $cms);               // embed a detached CMS into a prepared PDF\nAtick::prepareFields($pdf, $options);        // make an empty signature field (template)\nAtick::signField($pdf, $pfx, $options);      // sign an existing empty field\nAtick::setMetadata($pdf, $options);          // Title / Author / Subject / Keywords / …\nAtick::addDocTimestamp($pdf, $options);      // archive DocTimeStamp (PAdES-B-LTA)\nAtick::setFastSigning(true | false);         // revocation-cache toggle\nAtick::decrypt($pdf, $password);             // decrypt a password-protected PDF\nAtick::version();                            // engine version\n```\n\nEvery method is **static**. `$options` is a PHP **array** (recommended) or a JSON **string**. All\nbuffers are PHP binary strings. Any failure throws `Aniketc068\\ATick\\AtickException` whose\n`getMessage()` is the reason.\n\n### Options\n\n`cn, org, ou, location, reason, text, date, dn, body, heading, show_mark, green_tick, always_check,\nmark_color (hex / name / [r,g,b]), mark_gradient, mark_scale, text_color, bg_color, border, font_size,\nwidth, height, page, rect, placements ([[page,[x1,y1,x2,y2]], …]), mode (single/shared), field_name,\npades, hash_algo (sha256/384/512), timestamp, tsa_url, tsa_auth, ltv, lta, certify, lock_fields,\nverify, verify_expiry, verify_crl, verify_ocsp, open_password, encrypt_password, owner_password,\ncontents_size`.\n\n---\n\n## The mark\n\n```php\n['green_tick' =\u003e true]      // the \"?\" mark — Adobe paints it GREEN for valid+trusted, RED if invalid\n['always_check' =\u003e true]    // the green-tick graphic as the base\n['green_tick' =\u003e false]     // no mark — a plain signature\n```\n\nColour it: `'mark_color' =\u003e '#E53935'`, `'blue'`, `[255,140,0]` — or a gradient\n`'mark_gradient' =\u003e ['red','orange','yellow']`.\n\n---\n\n## Deferred signing \u0026 Indian eSign (two-step)\n\nWhen the private key lives elsewhere (a token / HSM / smart-card, or an eSign ESP):\n\n```php\n[$prepared, $bytesToSign] = Atick::prepare($pdf, [\n    'cn' =\u003e 'DS TEST', 'reason' =\u003e 'eSign',\n    'placements' =\u003e [[1, [300, 55, 575, 175]]], 'contents_size' =\u003e 16384,\n]);\n\n// the eSign InputHash is the SHA-256 of $bytesToSign:\n$inputHash = hash('sha256', $bytesToSign);\n// ... sign with your provider / eSign ESP, get back a detached CMS ...\n\n$signed = Atick::embed($prepared, $cms);\n```\n\n---\n\n## PAdES levels\n\n```php\nAtick::signPfx($pdf, $pfx, ['pades' =\u003e true]);                                            // B-B\nAtick::signPfx($pdf, $pfx, ['pades' =\u003e true, 'timestamp' =\u003e true]);                       // B-T\nAtick::signPfx($pdf, $pfx, ['pades' =\u003e true, 'timestamp' =\u003e true, 'ltv' =\u003e true]);        // B-LT\nAtick::signPfx($pdf, $pfx, ['pades' =\u003e true, 'timestamp' =\u003e true, 'lta' =\u003e true]);        // B-LTA\n```\n\n---\n\n## Compatibility — one package everywhere\n\n- **PHP 7.4 → the latest 8.x** — FFI is part of every supported PHP version.\n- **Every OS/arch** — the matching engine ships for each platform and is selected automatically:\n\n  | OS · arch | Covers |\n  |---|---|\n  | `windows-x86_64` / `windows-i686` | **Windows 7 → 11**, 64 / 32-bit |\n  | `windows-aarch64` | Windows on ARM64 |\n  | `linux-x86_64` / `linux-aarch64` / `linux-arm` / `linux-i686` | Linux x64 / ARM64 / ARM / 32-bit (glibc 2.17+, every distro) |\n  | `darwin-x86_64` / `darwin-aarch64` | macOS Intel / Apple Silicon |\n\n---\n\n## Errors\n\n```php\nuse Aniketc068\\ATick\\AtickException;\n\ntry {\n    Atick::signPfx($pdf, $pfx, ['password' =\u003e 'wrong']);\n} catch (AtickException $e) {\n    error_log('signing failed: ' . $e-\u003egetMessage());\n}\n```\n\n---\n\n## License\n\nATick is **dual-licensed** — free for personal \u0026 open use, paid if you sell:\n\n- **Free under [GNU AGPL-3.0](LICENSE)** — personal projects, learning, internal use, and\n  open-source projects (released publicly under AGPL-3.0).\n- **Commercial license (paid)** — if you **build a product with ATick and sell it**, or use it in a\n  **closed-source / commercial** product, you must buy a commercial license first. Contact\n  **aniketc.pro@gmail.com** for a quote.\n\nSee [LICENSING.md](LICENSING.md) for details. © 2026 Aniket Chaturvedi.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faniketc068%2Fatick-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faniketc068%2Fatick-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faniketc068%2Fatick-php/lists"}