eimzo-ts

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#7yesno — send the data separately
Server check/backend/pkcs7/verify/attached/backend/pkcs7/verify/detached, body dataBase64|pkcs7
Good forshort texts, JSON, formsfiles 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

  1. Every signer: verified, certificateVerified, certificateValidAtSigningTime are true; revokedStatusInfo is empty.
  2. The signed document is the one you expected (compare documentBase64).
  3. The signer's PINFL/TIN matches the logged-in user.
  4. A timestamp is present.
  5. 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