eimzo-client

Modern, typed, framework-agnostic E-IMZO (O'zbekiston ERI) client for the web — eimzo-client. Angular, Vue 3, React and Nuxt 3 adapters, inline WebSocket transport, mobile detection.
2,757
Install
npm install eimzo-client
Latest Version:0.2.1
Vue:3
License:MIT
Last Updated:Aug 19, 2026
Links: npm
Maintainer: qobiljon_dev

eimzo-client

Zamonaviy, TypeScript bilan to'liq typed, framework-agnostik E-IMZO (O'zbekiston ERI) klienti — web ilovalar uchun. Vue 3, React, Angular va Nuxt 3 adapterlari ham ichida.

npm install eimzo-client
import { createEimzo } from 'eimzo-client'

const eimzo = createEimzo()
await eimzo.install()                       // 1. E-IMZO'ga ulanish
const certs = await eimzo.listKeys()        // 2. Sertifikatlar ro'yxati
const { pkcs7 } = await eimzo.sign(certs[0], 'Imzolanadigan matn')  // 3. Imzolash

Asosiy imkoniyatlar

  • ✅ 100% mustaqil — tashqi e-imzo.js skript yuklanmaydi (ichki WebSocket transport)
  • ✅ Promise-asosli API (callback-hell yo'q), to'liq TypeScript typed
  • ✅ E-IMZO v5 va v6 bilan mos (v6 da API-key avtomatik)
  • ✅ PFX sertifikatlar + ID-card / BAIK / CKC qurilmalari
  • ✅ PKCS#7 imzolash + Timestamp (TST) ulash + katta fayllar uchun SHA-256 hash imzolash
  • ✅ Mobil ID-card QR / deeplink (eimzo-client/mobile-idcard)
  • ✅ Vue 3 plugin + composable, React Provider + hook, Angular Signal'lar, Nuxt module
  • ✅ ESM + CJS, tree-shake mos, 32 MB hujjatgacha imzolash (v6 limiti)
  • ✅ Xavfsizlik: SRI, prototype-pollution himoyasi, AbortSignal bilan bekor qilish

Mundarija

  1. E-IMZO qanday ishlaydi? — avval shu yerni o'qing
  2. O'rnatish va talablar
  3. Tezkor boshlash (vanilla)
  4. Hayotiy sikl: 4 qadam
  5. Framework adapterlari — Vue / Nuxt / React / Angular
  6. Imzolash holatlari
  7. Qurilma orqali kirish (ID-card / BAIK / CKC)
  8. Mobil ID-card (QR + deeplink)
  9. Timestamp (TST) qo'shish
  10. Transport rejimi
  11. API ma'lumotnomasi
  12. Xavfsizlik
  13. E-IMZO v6 yangiliklari

E-IMZO qanday ishlaydi?

E-IMZO — foydalanuvchi kompyuteriga o'rnatiladigan ERI (elektron raqamli imzo) dasturi. U fonda localhost'da WebSocket server sifatida ishlaydi (wss://127.0.0.1:64443). Brauzer shu serverga ulanib, kalitlar ro'yxatini oladi va imzolash buyruqlarini yuboradi.

eimzo-client — aynan shu WebSocket aloqasining toza, tipli o'ramidir. Maxsus tashqi skript yuklamaydi (ichki transport).

Tipik oqim har doim 2 tomonda ketadi — frontend imzolaydi, backend tekshiradi:

┌──────────┐   1. install / listKeys / sign   ┌─────────────────┐
│ Brauzer  │ ───────────────────────────────► │  E-IMZO daemon  │
│ (sizning │ ◄─────────────────────────────── │ (localhost WS)  │
│   sayt)  │        PKCS#7 imzo                └─────────────────┘
└────┬─────┘
     │ 2. PKCS#7 ni backendga yuborasiz
     ▼
┌──────────┐   imzoni tekshirish (e-imzo-server)
│ Backend  │ ──────────────────────────────────►  vpn.e-imzo.uz
└──────────┘

⚠️ Muhim: bu paket faqat frontend qismini bajaradi (imzo hosil qilish). Imzo haqiqiyligini, sertifikat statusini va challenge mosligini backend tekshirishi shart (e-imzo-server). Qarang: Xavfsizlik.

Uchta ishchi muhit bor:

Muhit Nima ishlatiladi Qanday
Desktop PFX sertifikatlar localhost WebSocket orqali to'g'ridan-to'g'ri
Desktop qurilma ID-card / BAIK / CKC xuddi shu, daemon PIN'ni o'zi so'raydi
Mobil E-IMZO ID-CARD ilovasi QR / deeplink + backend polling (pastga)

O'rnatish va talablar

npm install eimzo-client
# yoki
pnpm add eimzo-client
# yoki
yarn add eimzo-client

Talab: foydalanuvchi kompyuterida E-IMZO dasturi o'rnatilgan va ishga tushirilgan bo'lishi kerak. Aks holda install() EimzoNotInstalledError tashlaydi.


Tezkor boshlash (vanilla)

import { createEimzo } from 'eimzo-client'

const eimzo = createEimzo({
  // v5 uchun API-key'lar (v6 da kerak emas — E-IMZO o'zi o'rnatadi):
  apiKeys: {
    'localhost': '96D0C1491615C82B...',
    'mysite.uz': 'C691454C3DBAC565...',
  },
})

await eimzo.install()                  // skript/version/apikey
const certs = await eimzo.listKeys()   // PFX sertifikatlari
const result = await eimzo.sign(certs[0], 'Imzolanadigan matn')
console.log(result.pkcs7)              // base64 PKCS#7

v6: apiKeys opsiyasi e'tiborga olinmaydi — E-IMZO domenni o'zi avtomatik aniqlaydi.


Hayotiy sikl: 4 qadam

Deyarli har bir oqim shu to'rt qadamdan iborat. Tartibni saqlash muhim.

// 1. ULANISH — E-IMZO'ni topadi, versiyani aniqlaydi, API-key o'rnatadi
await eimzo.install()

// 2. RO'YXAT — mavjud PFX sertifikatlarni oladi (rol flag'lari avtomatik qo'shiladi)
const certs = await eimzo.listKeys()

// 3. TANLASH — foydalanuvchi UI'dan bittasini tanlaydi
const cert = certs[0]

// 4a. KIRISH (auth) — backend bergan challenge'ni imzolaydi
const challenge = await fetch('/api/auth/challenge').then(r => r.text())
const pkcs7 = await eimzo.authenticate(challenge, cert)
await fetch('/api/auth/login', { method: 'POST', body: pkcs7 })

// 4b. yoki HUJJAT IMZOLASH
const { pkcs7: signed } = await eimzo.sign(cert, JSON.stringify({ orderId: 12345 }))
  • authenticate() — kirish (login) uchun: backend tasodifiy challenge beradi, foydalanuvchi uni imzolaydi, backend imzoni tekshirib sessiya ochadi.
  • sign() — hujjat imzolash uchun: natija backendda arxivlanadi / tekshiriladi.

Framework adapterlari

Core API (createEimzo()) har bir metodga sertifikatni argument sifatida beradi. Adapter'larda esa (useEimzo() / EimzoService) sertifikat ichki state'da saqlanadi — qarang: Adapter API qoidalari.

Vue 3

// main.ts
import { createApp } from 'vue'
import { EimzoVuePlugin } from 'eimzo-client/vue'
import App from './App.vue'

createApp(App)
  .use(EimzoVuePlugin, { apiKeys: { 'localhost': '96D0C1491615C82B...' } })
  .mount('#app')
<!-- KeySelector.vue -->
<script setup lang="ts">
import { onMounted } from 'vue'
import { useEimzo } from 'eimzo-client/vue'

const { certificates, selected, loading, error, loadCertificates, select, sign } = useEimzo()

onMounted(loadCertificates)

async function onSign() {
  const result = await sign('Hujjat matni')
  console.log(result.pkcs7)
}
</script>

<template>
  <div v-if="loading">Yuklanmoqda...</div>
  <div v-else-if="error">{{ error.message }}</div>

  <ul>
    <li v-for="c in certificates" :key="c.serialNumber" @click="select(c)">
      {{ c.CN }} ({{ c.TIN || c.PINFL }})
    </li>
  </ul>

  <button :disabled="!selected" @click="onSign">Imzolash</button>
</template>

Nuxt 3

Module sifatida ulang — useEimzo() avto-import bo'ladi:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['eimzo-client/nuxt'],
  eimzo: {
    apiKeys: { 'mysite.uz': process.env.NUXT_PUBLIC_EIMZO_KEY ?? '' },
    transport: 'inline',   // 'inline' (default) | 'external'
    onMobile: 'throw',     // 'throw' (default) | 'warn' | 'ignore'
  },
})
<!-- pages/sign.vue -->
<script setup lang="ts">
const { certificates, selected, error, install, loadCertificates, select, sign } = useEimzo()

onMounted(async () => {
  await install()
  await loadCertificates()
})

async function onSign() {
  if (!selected.value) return
  const result = await sign('Imzolanadigan matn')
  await $fetch('/api/sign', { method: 'POST', body: { pkcs7: result.pkcs7 } })
}
</script>

SSR: plugin faqat brauzerda ishlaydi (E-IMZO daemon localhost'da bo'lgani uchun). install() va boshqa metodlarni onMounted() ichida (yoki <client-only> blokida) chaqiring.

React

// main.tsx
import { EimzoProvider } from 'eimzo-client/react'

ReactDOM.createRoot(root).render(
  <EimzoProvider options={{ apiKeys: { 'localhost': '96D0C1...' } }} autoInstall>
    <App />
  </EimzoProvider>
)
// KeySelector.tsx
import { useEffect } from 'react'
import { useEimzo } from 'eimzo-client/react'

export function KeySelector() {
  const { certificates, selected, loading, error, loadCertificates, select, sign } = useEimzo()

  useEffect(() => { loadCertificates() }, [loadCertificates])

  if (loading) return <div>Yuklanmoqda...</div>
  if (error) return <div>{error.message}</div>

  return (
    <>
      <ul>
        {certificates.map(c => (
          <li key={c.serialNumber} onClick={() => select(c)}>
            {c.CN} ({c.TIN || c.PINFL})
          </li>
        ))}
      </ul>
      <button disabled={!selected} onClick={() => sign('Hujjat matni')}>Imzolash</button>
    </>
  )
}

Angular (≥17)

Versiya talabi: Angular 17+. Adapter reaktiv holati Signal'larga (signal, .asReadonly()) tayanadi — ular v17'dan barqaror (v16'da developer-preview). inject() v14'dan bor, lekin Signal barqarorligi chegarani belgilaydi.

EimzoService ataylab providedIn: 'root' emas — uni doim provideEimzo() yoki provideEimzoClient() orqali ro'yxatdan o'tkazing. Servis dekoratorsiz yozilgan va useFactory orqali beriladi, shuning uchun paket Angular kompilyatori talab qilmasdan AOT/production build'da JIT'siz ishlaydi.

Standalone API + Signal'lar bilan. provideEimzo() orqali sozlanadi:

// app.config.ts
import { provideEimzo } from 'eimzo-client/angular'

export const appConfig = {
  providers: [provideEimzo({ apiKeys: { 'mysite.uz': '...' } })],
}
// key-selector.component.ts
import { Component, inject, OnInit } from '@angular/core'
import { EimzoService } from 'eimzo-client/angular'

@Component({ standalone: true, selector: 'app-key-selector', template: `...` })
export class KeySelectorComponent implements OnInit {
  readonly eimzo = inject(EimzoService)

  async ngOnInit() {
    await this.eimzo.install()
    await this.eimzo.loadCertificates()
  }

  async onSign() {
    const result = await this.eimzo.sign('Hujjat matni')
    console.log(result.pkcs7)
  }
}

EimzoService reaktiv field'lari (Signal): certificates(), selected(), loading(), error(), version().

Tayyor EimzoClient'ni ham berish mumkin (test / shared client uchun):

import { provideEimzoClient } from 'eimzo-client/angular'
import { createEimzo } from 'eimzo-client'

providers: [provideEimzoClient(createEimzo({ apiKeys: { /* ... */ } }))]

Adapter API qoidalari

Adapter'larda imzolash metodlaridan oldin selected'ga sertifikat qo'yilishi shart, aks holda Error("Sertifikat tanlanmagan") qaytariladi.

Sertifikat tanlash:

// Vue — uch ekvivalent yo'l:
select(cert)            // 1. select() metodi
selected.value = cert   // 2. ref'ga to'g'ridan-to'g'ri
// 3. template'da: <select v-model="selected">

// React / Angular — faqat select():
select(cert)

Qaysi metod selected talab qiladi:

Metod selected kerakmi? Sabab
install() / loadCertificates() / select() ❌ Sertifikatsiz ishlaydi
sign(data, opts?) ✅ selected'dan oladi
signHash(file, opts?) ✅ selected'dan oladi
authenticate(challenge) ✅ selected'dan oladi
signWithSerial(serial, data) ❌ Serial bo'yicha topadi
// To'g'ri tartib:
await install()                        // 1
const certs = await loadCertificates() // 2
select(certs[0])                       // 3 ⚠️ MAJBURIY — o'tkazib yuborilsa, authenticate xato beradi
const pkcs7 = await authenticate(challenge) // 4

💡 Sertifikatni state'da saqlamasdan ishlash uchun core API'ni (createEimzo()) ishlating.


Imzolash holatlari

Misollar core API uchun. Adapter'larda cert'ni argument sifatida bermaysiz — selected'dan olinadi.

sign() qabul qiladigan turlar:

type BinaryInput = string | ArrayBuffer | ArrayBufferView | Blob

1. Auth challenge (matn):

const challenge = await fetch('/api/auth/challenge').then(r => r.text())
const pkcs7 = await eimzo.authenticate(challenge, cert)

2. JSON hujjat:

const result = await eimzo.sign(cert, JSON.stringify({ orderId: 12345, amount: 1_000_000 }))

3. PDF/DOC fayl (Blob/File):

const file = inputElement.files[0]
const result = await eimzo.sign(cert, file)

4. Katta fayl — SHA-256 hash imzolash (10+ MB uchun tavsiya etiladi):

const { pkcs7, hash } = await eimzo.signHash(cert, file)  // avto SHA-256 + detached PKCS#7
await fetch('/api/sign', {
  method: 'POST',
  body: JSON.stringify({ pkcs7, hashHex: bytesToHex(hash) }),
})

5. Binary baytlar:

const result = await eimzo.sign(cert, new Uint8Array([0x01, 0x02, 0x03]))

6. Allaqachon base64 satr:

const result = await eimzo.sign(cert, alreadyBase64, { isBase64: true })

7. Detached imzo (asl hujjatsiz):

const result = await eimzo.sign(cert, file, { detached: true })  // PKCS#7 ichida fayl yo'q

Qurilma orqali kirish (ID-card / BAIK / CKC)

Bu uchta qurilma sertifikat ro'yxatiga kirmaydi (listKeys() ularni qaytarmaydi) — alohida tugma orqali ishlatiladi. PIN'ni E-IMZO daemon o'zi so'raydi (JS tomondan load_key/verify_pin chaqirilmaydi).

if (await eimzo.isBaikConnected()) {
  const challenge = await fetch('/api/challenge').then(r => r.text())
  const pkcs7 = await eimzo.authenticateWithBaik(challenge)
  await fetch('/api/login', { method: 'POST', body: pkcs7 })
}
Metod Tavsif
isIdCardConnected() / isBaikConnected() / isCkcConnected() Qurilma ulanganmi?
signWithIdCard(data, opts?) / signWithBaik(...) / signWithCkc(...) Imzolash
authenticateWithIdCard(challenge) / authenticateWithBaik(...) / authenticateWithCkc(...) Challenge imzolash
signWithDevice(device, data, opts?) Umumiy variant (device: 'idcard'/'baikey'/'ckc')

Versiya talabi: ID-card uchun E-IMZO 4.12+, BAIK/CKC uchun 4.86+. Eski versiyada EimzoVersionError tashlanadi.


Mobil ID-card (QR + deeplink)

E-IMZO desktop dasturi telefonda yo'q — uning o'rniga E-IMZO ID-CARD mobile ilovasi ishlatiladi. U butunlay boshqa, REST-API asosidagi oqim (qo0p/e-imzo-doc, 3-bo'lim):

  1. Backend POST /frontend/mobile/auth → { siteId, documentId, challange }
  2. Frontend challange'dan GOST hash + CRC32 hisoblab qc quradi:
    • web (desktop) — qc QR rasm bo'lib chiziladi, foydalanuvchi telefon bilan skanlaydi
    • same-device (mobil brauzer) — eimzo://... deeplink ochiladi
  3. POST /frontend/mobile/status (documentId=…) ni status:1 bo'lguncha poll qilamiz
  4. Backend GET /backend/mobile/authenticate/{documentId} orqali tasdiqlaydi

QR/deeplink quruvchi alohida, tree-shake'lanadigan subpath'da: eimzo-client/mobile-idcard (GOST jadvallari faqat shuni import qilgan bundle'ga kiradi).

⚠️ GOST hash'ni frontend hisoblaydi — bu rasmiy protokol talabi, backend tayyor qc qaytarmaydi. Bu modul rasmiy e-imzo-mobile.js ning toza TS ekvivalenti (7/7 GOST test-vektori + real skanlangan QR bilan tasdiqlangan), shuning uchun tashqi skript yuklash shart emas.

import { buildIdCardMobileQr } from 'eimzo-client/mobile-idcard'
import { pollMobileResult, isMobilePlatform } from 'eimzo-client'
import QRCode from 'qrcode'

// 1. Backend auth sessiyasini yaratadi
const auth = await fetch('/frontend/mobile/auth', { method: 'POST' }).then(r => r.json())
// { siteId, documentId, challange }

// 2. qc / deeplink / hash quramiz
const { qc, deeplink, hash } = buildIdCardMobileQr(auth)

if (isMobilePlatform()) {
  window.location.href = deeplink        // same-device: ilovani ochamiz
} else {
  const dataUrl = await QRCode.toDataURL(qc)  // desktop: QR chizamiz (boshqa telefon skanlaydi)
}
// `hash` — QR yonida ko'rsatiladigan "hesh-kod"; foydalanuvchi ilovadagi bilan solishtiradi

// 3. status:1 bo'lguncha poll qilamiz
await pollMobileResult(
  async () => {
    const r = await fetch('/frontend/mobile/status', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: `documentId=${encodeURIComponent(auth.documentId)}`,
    }).then(r => r.json())
    return r.status === 1 ? { ready: true, data: r } : { ready: false }
  },
  { intervalMs: 2000, timeoutMs: 5 * 60 * 1000 },
)

// 4. Backend tasdiqlaydi:
//    GET /backend/mobile/authenticate/{documentId} → { status:1, subjectCertificateInfo }

eimzo-client/mobile-idcard eksportlari:

Funksiya Tavsif
buildIdCardMobileQr({ siteId, documentId, challange }) { qc, deeplink, hash } quradi
gostHash(text) GOST R 34.11-94 hash (ASCII matn — login/auth uchun)
gostHashHex(hex) GOST hash (hex input — hujjat imzolash uchun)
crc32Hex(hex) CRC32, 8 belgi lowercase hex

Platformani aniqlash: getPlatform() → 'ios' | 'android' | 'desktop' | 'unknown', isMobilePlatform() → boolean. Default'da install() mobil brauzerda EimzoMobileUnsupportedError tashlaydi (onMobile: 'throw').


Timestamp (TST) qo'shish

Imzoga ishonchli vaqt belgisi ulash uchun timestamp callback bering:

const result = await eimzo.sign(cert, data, {
  async timestamp(signatureHex) {
    return fetch('/api/timestamp', { method: 'POST', body: signatureHex }).then(r => r.text())
  },
})

Transport rejimi

Default — inline: paket o'zining WebSocket transportini ishlatadi, tashqi skript yuklamaydi.

const eimzo = createEimzo({ transport: 'inline' })  // DEFAULT

Eski window.CAPIWS skriptiga tayanish (legacy):

const eimzo = createEimzo({
  transport: 'external',
  scriptUrl: 'https://e-imzo.uz/e-imzo-cm/e-imzo.js',
  scriptIntegrity: 'sha384-...',  // SRI tavsiya etiladi
})
Xususiyat inline (default) external
Tashqi skript yuklash ❌ Yo'q ✅ e-imzo.uz dan ≈50KB
Supply-chain xavfi ✅ Yo'q ⚠️ CDN xavfi (SRI bilan kamayadi)
CSP script-src Faqat 'self' 'self' https://e-imzo.uz
WebSocket bekor qilish (AbortSignal) ✅ Bor ❌ Yo'q
Birinchi imzo tezligi ⚡ Tezroq Skript yuklash kutiladi
Offline (intranet) ✅ Ishlaydi ❌ e-imzo.uz kerak

Tavsiya: production'da inline'da qoldiring. external faqat eski integratsiyalar uchun.


API ma'lumotnomasi

createEimzo(options): EimzoClient

Opsiya Tip Default Tavsif
apiKeys Record<string, string> — domen → key (faqat v5; v6 da e'tiborsiz)
transport 'inline' | 'external' 'inline' Transport rejimi
capiwsUrl string wss://127.0.0.1:64443/... Inline mode WebSocket URL
scriptUrl string e-imzo.uz CDN External mode skript URL
skipScriptLoad boolean false Skript allaqachon mavjud bo'lsa
scriptIntegrity string — External mode SRI hash
timeoutMs number 0 (timeout yo'q) Har bir CAPIWS chaqiruv timeout'i
maxDataBytes number 32 MB Imzolanadigan ma'lumot maks hajmi
onMobile 'throw' | 'warn' | 'ignore' 'throw' Mobil brauzerda install() xatti-harakati

timeoutMs default 0 — chunki load_key/create_pkcs7 foydalanuvchidan parol kutadi. Programmatik chaqiruvlar uchun > 0 bering.

EimzoClient metodlari

Metod Tavsif
install() Ulanish: version aniqlash + apikey o'rnatish (external'da skript ham)
listKeys() PFX sertifikatlar ro'yxati (rol flag'lari bilan)
loadKey(cert, { verify }) Kalitni yuklash, ixtiyoriy parol/PIN tekshiruvi
sign(cert, data, opts?) PKCS#7 imzolash
signWithSerial(serial, data, opts?) Serial bo'yicha topib imzolash
signHash(cert, file, opts?) SHA-256 hash + detached PKCS#7
authenticate(challenge, cert) Auth challenge'ni imzolash
getCertificateChain(handle) x509 sertifikat zanjiri
isIdCardConnected() / isBaikConnected() / isCkcConnected() Qurilma ulanganmi
signWithDevice(device, data, opts?) Qurilma orqali imzolash (umumiy)
signWithIdCard(...) / signWithBaik(...) / signWithCkc(...) Qurilma orqali imzolash (qisqartma)
authenticateWithIdCard(...) / authenticateWithBaik(...) / authenticateWithCkc(...) Challenge imzolash
version Versiya ma'lumoti (install() dan keyin)

Sertifikat yordamchilari

Har bir Certificate listKeys() paytida avtomatik rol flag'lari bilan boyitiladi:

const cert = (await eimzo.listKeys())[0]
cert.isLegalEntity        // yuridik shaxsmi?
cert.isPhysicalPerson     // jismoniy shaxs (YATT ham kiradi)?
cert.isYATT               // yakka tartibdagi tadbirkor?

Free-funksiyalar (Pick'lar bilan ham ishlaydi):

import {
  isLegalEntity, isPhysicalPerson, isYATT,
  getCertificateRole, getCertificateRoleLabel, getCertificateStatus,
} from 'eimzo-client'

getCertificateRole(cert)              // 'legal' | 'yatt' | 'physical'
getCertificateRoleLabel(cert)         // "Yuridik shaxs" | "Yakka tartibdagi tadbirkor" | "Jismoniy shaxs"
getCertificateRoleLabel(cert, 'en')   // inglizcha variant
getCertificateStatus(cert)            // { status: 'active'|'expiring'|'expired'|'pending', daysLeft }

Encoding yordamchilari

import {
  encodeBase64, encodeBase64Async, decodeBase64, decodeBase64Text,
  bytesToHex, hexToBytes, sha256, sha256Hex, sha256Base64, byteLength,
} from 'eimzo-client'

encodeBase64('Salom dunyo')             // UTF-8 → base64
await encodeBase64Async(file)           // Blob/File → base64
decodeBase64Text('SGVsbG8=')            // base64 → string
await sha256Hex(file)                   // SHA-256 hex
bytesToHex(new Uint8Array([0xab, 0xcd])) // 'abcd'

Native fast path: Uint8Array.prototype.toBase64() mavjud bo'lgan brauzerlarda (Chrome 130+, Safari 18+) avtomatik undan foydalanadi; eski brauzerlarda chunked btoa (32 MB gacha stack overflow yo'q).

Xato turlari

Hammasi EimzoError'dan meros oladi va code xususiyatiga ega.

Xato Qachon
EimzoNotInstalledError E-IMZO dasturi ishlamayapti
EimzoTransportError WebSocket / tarmoq xatosi
EimzoVersionError E-IMZO versiyasi mos kelmadi
EimzoApiKeyError API-key noto'g'ri yoki yo'q
EimzoTimeoutError Chaqiruv kutish vaqti tugadi
EimzoWrongPasswordError Noto'g'ri PFX parol / token PIN
EimzoSignError Imzolashda xatolik
EimzoKeyNotFoundError Sertifikat topilmadi
EimzoDataTooLargeError Ma'lumot maxDataBytes'dan oshdi
EimzoResponseTooLargeError Daemon javobi juda katta
EimzoMobileUnsupportedError Mobil brauzerda install() chaqirilgan
import { EimzoError, EimzoNotInstalledError, EimzoWrongPasswordError } from 'eimzo-client'

try {
  await eimzo.signWithBaik(data)
} catch (e) {
  if (e instanceof EimzoNotInstalledError) alert('E-IMZO dasturini ishga tushiring')
  else if (e instanceof EimzoWrongPasswordError) alert("Noto'g'ri PIN")
  else if (e instanceof EimzoError) console.error(e.code, e.message)
}

Xavfsizlik

E-IMZO bilan ishlashda frontend imzo hosil qiladi, lekin tekshirmaydi. Backend tomonida quyidagilar majburiy.

Auth (login) checklist

  • ✅ Challenge tasodifiyligi — kamida 32 bayt CSPRNG (crypto.randomBytes(32))
  • ✅ TTL ≤ 5 daqiqa — challenge cache'da muddati cheklangan (masalan, Redis TTL)
  • ✅ Bir martalik — verify'dan keyin challenge'ni darhol o'chiring
  • ✅ Origin/audience binding — challenge ichida saytingiz host'i bo'lsin
  • ✅ Sertifikat zanjiri — Root CA gacha tekshiring (E-IMZO PKI'siga ishonch)
  • ✅ Sertifikat statusi — validFrom <= now <= validTo, mumkin bo'lsa CRL/OCSP
  • ✅ PKCS#7 imzosi GOST/RSA bilan tekshirilgan va challenge baytlariga mos

Token saqlash

localStorage JWT uchun zaif (XSS'da o'g'irlanadi):

  • 🟢 HttpOnly + Secure + SameSite=Strict cookie
  • 🟡 Qisqa TTL (15–30 min) + refresh token rotation
  • 🔴 localStorage — faqat development yoki token bo'lmagan narsa uchun

ID-card mobil oqim xavfsizligi

  • ✅ documentId/challange ni backend yaratadi — frontend faqat GOST hash/CRC32 quradi. siteId ro'yxatdan o'tgan UPLOAD URL'ga bog'langan, shuning uchun PKCS#7 faqat sizning /frontend/mobile/upload ga keladi.
  • ✅ challange bir martalik + qisqa TTL — har auth da yangi challange, backend Redis'da cheklangan muddat saqlaydi.
  • ✅ Yakuniy tekshiruv backendda — frontend'dagi status:1 o'zi yetarli emas; foydalanuvchi ma'lumoti /backend/mobile/authenticate/{documentId} javobidan olinadi.
  • ✅ hash ("hesh-kod") ni foydalanuvchiga ko'rsating — ilovadagi bilan ko'z bilan solishtirish phishing'ni kamaytiradi.

Localhost daemon TLS

E-IMZO daemon wss://127.0.0.1:64443 da self-signed sertifikat ishlatadi (pinning yo'q). Lokal mashinadagi zararli proses portga "o'tirib" imzolarni tutib qolishi mumkin — bu paket buni oldini olmaydi (tahdid model — OS-level malware). Mitigatsiya: ishonchli mashina, antivirus, host-based IDS.

CSP tavsiyalari

script-src 'self';                               # inline mode
connect-src 'self' wss://127.0.0.1:* ws://127.0.0.1:*;

External mode'da script-src ga https://e-imzo.uz qo'shing va scriptIntegrity (SRI) bering.


E-IMZO v6 yangiliklari

Paket avtomatik aniqlaydi va moslashadi:

  • ✅ API-KEY avtomatik o'rnatiladi (apikey chaqiruv kerak emas)
  • ✅ 32 MB gacha hujjat imzolash
  • ✅ ID-card emulyatori (test rejimi)
  • ✅ UZGUARD token qo'llab-quvvatlash
  • ✅ JRE 17 → JRE 1.8 PFX moslik

Bog'lanish

Muallif: Qobiljon Jumaboyev

Savol, taklif yoki xavfsizlik muammolari uchun yuqoridagi kanallar orqali bog'laning.


Litsenziya

MIT © Qobiljon Jumaboyev

Related Packages

eimzo-sign-vue

Vue 2.7 / Vue 3 uchun E-IMZO imzolash modali: sertifikat tanlash, WYSIWYS ko'rin...

2,602
ziko-wrapper

integrate zikojs elements within other ui framework like vue react solidjs svelt...

5,604 49
@federa/solanda-ui

Minimalist Web Components UI library for Vue, Nuxt, React, and Angular

2,590
clientforge

Front-end SDK generator from OpenAPI specifications — supports Angular, Vue, and...

172 0
vite-plugin-dev-inspector

jump to local IDE source code while click the element of browser automatically.

6,946 51

Version History

Version Released Vue License
0.2.1 >=3.0.0 MIT
0.2.0 >=3.0.0 MIT
0.1.9 >=3.0.0 MIT
0.1.8 >=3.0.0 MIT
0.1.7 >=3.0.0 MIT