Signing documents and files with E-IMZO
Create a PKCS#7 (CMS) signature in the browser, add a timestamp, verify it on the server.
Load a key once
const keys = await eimzo.listKeys();
await eimzo.loadKey(keys.find((k) => !k.expired)!);
The loaded key's keyId is kept in the client. Later signatures reuse it, so E-IMZO does not ask
for the password again while it remembers it (1 minute, or 6 hours if the user ticks "Remember").
Attached or detached
Attached (default for sign) | Detached (default for signFile) | |
|---|---|---|
| The signed data is inside the PKCS#7 | yes | no — send the data separately |
| Server check | /backend/pkcs7/verify/attached | /backend/pkcs7/verify/detached, body dataBase64|pkcs7 |
| Good for | short texts, JSON, forms | files you store anyway |
const attached = await eimzo.sign('text or JSON');
const detached = await eimzo.sign(new Uint8Array(bytes), { detached: true });
const filePkcs7 = await eimzo.signFile(input.files[0]); // detached, 10 MB limit
const bigFile = await eimzo.signFile(file, { maxSize: 50 * 1024 * 1024 });
Strings are signed as UTF-8. If your string is already base64, pass { base64: true }.
Add a timestamp
The signingTime inside a PKCS#7 comes from the user's computer clock and can be wrong or faked.
A timestamp from a trusted server fixes the time of signing.
const pkcs7 = await eimzo.signDocument(JSON.stringify({ id: orderId, nonce: crypto.randomUUID(), total }));
await fetch(`/api/orders/${orderId}/sign`, { method: 'POST', headers: { 'Content-Type': 'text/plain' }, body: pkcs7 });
signDocument needs backend.timestamp: with createFetchBackend, set
timestampUrl to an endpoint that proxies POST /frontend/timestamp/pkcs7 and returns
{"status":1,"pkcs7b64":"..."}.
What the server must check
- Every signer:
verified,certificateVerified,certificateValidAtSigningTimeare true;revokedStatusInfois empty. - The signed document is the one you expected (compare
documentBase64). - The signer's PINFL/TIN matches the logged-in user.
- A timestamp is present.
- The unique ID inside the document was not used before (prevents replay).
The PKCS#7 contains the signer's certificate with personal data (PINFL). Store and log it accordingly.
Hardware devices
const { idcard, baikey, ckc } = await eimzo.listDevices();
if (idcard) {
await eimzo.loadKey('idcard');
const pkcs7 = await eimzo.sign('text');
}
See also: API reference · demo with a PKCS#7 viewer