Piekļūstiet sava seifa saturam programmatiski ar zero-knowledge šifrēšanu.
Kā iegūt un atšifrēt seifa vienumus ar Tag API v2
Tag API v2 nodrošina pilnu lasīšanas funkcionalitāti ar automātisku atšifrēšanu klienta pusē. Serveris atgriež šifrētus datus, ko jūs atšifrējat ar savu Decryption Key.
Pirms sākat
Pārliecinieties, ka esat izlasījis Autentifikācijas un Drošības sadaļas, lai saprastu atslēgu sistēmu un šifrēšanas principus.
/api/v2/tag/infoAtgriež pamatinformāciju par tagu un lietotāja publisko atslēgu.
| Parametrs | Tips | Apraksts |
|---|---|---|
X-API-Key* | string | Access Key (vgtk_a_xxx) |
{
"success": true,
"data": {
"tagId": "tag_abc123",
"tagName": "Mani MCP Dati",
"userPublicKey": "base64_encoded_public_key",
"mcpPublicKey": "base64_encoded_mcp_public_key",
"itemCount": 42,
"permissions": ["vault:read", "items:read", "items:write", "items:delete"]
}
}userPublicKey
userPublicKey ir galvenā lietotāja publiskā atslēga. To izmanto, lai izveidotu key slots, kas ļauj lietotājam atšifrēt datus ar savu master password.
/api/v2/tag/itemsAtgriež visus šifrētos vienumus, kas saistīti ar tagu.
| Parametrs | Tips | Apraksts |
|---|---|---|
X-API-Key* | string | Access Key (vgtk_a_xxx) |
| Parametrs | Tips | Apraksts |
|---|---|---|
type | string | Filtrēt pēc tipa: PASSWORD, NOTE, TOTP, IMAGE, DOCUMENT |
limit | number | Maksimālais vienumu skaits (noklusējums: 100) |
offset | number | Pāriešana (pagination) |
{
"success": true,
"data": {
"items": [
{
"id": "item_abc123",
"type": "PASSWORD",
"title": "GitHub Login",
"encryptedData": "base64_encrypted_data",
"iv": "base64_iv",
"keySlots": [
{
"keyId": "main",
"encryptedDEK": "base64_encrypted_dek",
"nonce": "base64_nonce",
"senderPublicKey": "base64_sender_public_key"
},
{
"keyId": "vgtk_a_xxxxxxx",
"encryptedDEK": "base64_encrypted_dek",
"nonce": "base64_nonce",
"senderPublicKey": "base64_sender_public_key"
}
],
"labels": ["tag_abc123"],
"createdAt": "2024-01-15T12:00:00Z",
"updatedAt": "2024-01-15T12:00:00Z"
}
],
"total": 42,
"hasMore": true
}
}PBKDF2(decryptKey, salt, 100000) → NaCl keypair
Meklē keySlot ar keyId = pirmie 15 simboli no Access Key
nacl.box.open(encryptedDEK, nonce, senderPublicKey, secretKey)
AES-256-GCM decrypt(encryptedData, DEK, IV)
import nacl from 'tweetnacl'
import crypto from 'crypto'
const ACCESS_KEY = 'vgtk_a_xxxxxxxxxxxxxxxxxxxxx'
const DECRYPT_KEY = 'vgtk_d_xxxxxxxxxxxxxxxxxxxxx'
const MCP_SALT = 'vairogs-mcp-key-derivation-v1'
// 1. Atvasini keypair
function deriveKeypair(decryptKey: string) {
const seed = crypto.pbkdf2Sync(decryptKey, MCP_SALT, 100000, 32, 'sha256')
return nacl.box.keyPair.fromSecretKey(new Uint8Array(seed))
}
// 2. Utilītas
function base64ToUint8Array(base64: string) {
return new Uint8Array(Buffer.from(base64, 'base64'))
}
// 3. Atšifrē vienumu
function decryptItem(item: any, keypair: nacl.BoxKeyPair) {
// Atrodi pareizo key slot
const mcpKeyPrefix = ACCESS_KEY.substring(0, 15)
const keySlot = item.keySlots.find((s: any) => s.keyId === mcpKeyPrefix)
if (!keySlot) throw new Error('Key slot not found')
// Atšifrē DEK
const encryptedDEK = base64ToUint8Array(keySlot.encryptedDEK)
const nonce = base64ToUint8Array(keySlot.nonce)
const senderPublicKey = base64ToUint8Array(keySlot.senderPublicKey)
const dek = nacl.box.open(encryptedDEK, nonce, senderPublicKey, keypair.secretKey)
if (!dek) throw new Error('Failed to decrypt DEK')
// Atšifrē datus ar AES-GCM
const iv = base64ToUint8Array(item.iv)
const encryptedData = base64ToUint8Array(item.encryptedData)
const authTag = encryptedData.slice(-16)
const ciphertext = encryptedData.slice(0, -16)
const decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(dek), iv)
decipher.setAuthTag(authTag)
const decrypted = Buffer.concat([
decipher.update(ciphertext),
decipher.final()
])
return JSON.parse(decrypted.toString('utf8'))
}
// Izmantošana
async function main() {
const keypair = deriveKeypair(DECRYPT_KEY)
const response = await fetch('https://vairogs.lv/api/v2/tag/items', {
headers: { 'X-API-Key': ACCESS_KEY }
})
const { data } = await response.json()
for (const item of data.items) {
const decryptedData = decryptItem(item, keypair)
console.log(`${item.title}:`, decryptedData)
}
}{
"username": "user@example.com",
"password": "secret123",
"url": "https://example.com",
"notes": "Papildu piezīmes"
}{
"content": "Piezīmes teksts..."
}{
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"account": "user@example.com",
"algorithm": "SHA1",
"digits": 6,
"period": 30
}{
"notes": "Apraksts",
"fileMetadata": {
"storagePath": "path/to/file",
"thumbnailPath": "path/to/thumb",
"originalFileName": "doc.pdf",
"mimeType": "application/pdf",
"fileSize": 102400
}
}Ar @vairogs/sdk atšifrēšana notiek automātiski:
import { VairogsClient } from '@vairogs/sdk'
const client = new VairogsClient({
accessKey: 'vgtk_a_xxx',
decryptionKey: 'vgtk_d_xxx'
})
// Get all items (already decrypted!)
const items = await client.getItems()
// Filter by type
const passwords = await client.getItems({ type: 'PASSWORD' })
// Get specific item
const item = await client.getItem('item_abc123')