Zum Hauptinhalt springen
Venice bietet Privacy-erweiterte Modelle, die in Trusted Execution Environments (TEE) laufen und Ende-zu-Ende-Verschlüsselung (E2EE) unterstützen. Diese Modelle liefern kryptografische Garantien, dass deine Daten privat bleiben — selbst gegenüber Venice.

Die Privacy-Stufen verstehen

TypPräfixWas es bedeutet
TEEtee-*Modell läuft in einer hardware-gesicherten Enklave. Venice kann nicht auf die Berechnung zugreifen. Du kannst das per Attestation verifizieren.
E2EEe2ee-*Vollständige Ende-zu-Ende-Verschlüsselung. Deine Prompts werden clientseitig verschlüsselt, bevor sie gesendet werden. Nur die TEE kann sie entschlüsseln.
E2EE-Modelle umfassen den TEE-Schutz plus clientseitige Verschlüsselung. TEE-Modelle bieten Enklaven-Sicherheit ohne clientseitige Verschlüsselung.

Verfügbare Modelle

Loading…
Die vollständige Liste mit Preisen und Kontext-Limits findest du auf der Modelle-Seite.

TEE-Modelle

TEE-Modelle laufen in hardware-gesicherten Enklaven (Intel TDX, NVIDIA Confidential Computing). Die Modellgewichte und deine Daten sind vor dem Host-System geschützt — einschließlich Venices Infrastruktur.

Grundlegende Nutzung

TEE-Modelle funktionieren genau wie reguläre Modelle:
from openai import OpenAI

client = OpenAI(
    api_key="your-venice-api-key",
    base_url="https://api.venice.ai/api/v1"
)

response = client.chat.completions.create(
    model="tee-qwen3-5-122b-a10b",
    messages=[{"role": "user", "content": "Explain quantum computing"}]
)

print(response.choices[0].message.content)

TEE-Attestation verifizieren

Du kannst kryptografisch verifizieren, dass ein Modell in einer echten TEE läuft, indem du seinen Attestation-Report abrufst:
# Eine zufällige Nonce erzeugen (verhindert Replay-Angriffe)
NONCE=$(openssl rand -hex 16)

# Attestation abrufen
curl "https://api.venice.ai/api/v1/tee/attestation?model=tee-qwen3-5-122b-a10b&nonce=$NONCE" \
  -H "Authorization: Bearer $API_KEY_VENICE"
Die Attestation-Antwort enthält:
FeldBeschreibung
verifiedOb die Attestation die serverseitige Verifikation bestanden hat
nonceDeine Nonce, bestätigt Frische
modelDie attestierte Modell-ID
tee_providerTEE-Provider-Kennung
intel_quoteRoher Intel-TDX-Quote (base64) für clientseitige Verifikation
nvidia_payloadNVIDIA-GPU-Attestation-Daten (falls zutreffend)
signing_keyÖffentlicher Schlüssel zur Verifikation der Response-Signaturen (typischerweise für E2EE-Flows nötig; bei manchen reinen TEE-Modellen kann er fehlen)
signing_addressAus dem Signing-Key abgeleitete Ethereum-Adresse
In der Produktion die Attestation clientseitig verifizieren, indem du den Intel-TDX-Quote parst und die NVIDIA-Attestation prüfst.
Für die Verifikation reiner TEE-Modelle reichen signing_address und die serverseitigen Verifikationsfelder für Baseline-Attestation-Checks. Ein signing_key wird benötigt, wenn du clientseitige E2EE-Schlüsselverhandlung und strikte Key-Binding-Checks brauchst.

Response-Signaturen

TEE-Modelle können ihre Antworten signieren und so beweisen, dass die Ausgabe aus der attestierten Enklave stammt:
# Nach einer Completion die Signatur verifizieren
curl "https://api.venice.ai/api/v1/tee/signature?model=tee-qwen3-5-122b-a10b&request_id=chatcmpl-abc123" \
  -H "Authorization: Bearer $API_KEY_VENICE"

E2EE-Modelle

E2EE-Modelle fügen dem TEE-Schutz clientseitige Verschlüsselung hinzu. Deine Prompts werden verschlüsselt, bevor sie dein Gerät verlassen, und nur die TEE kann sie entschlüsseln. Venice E2EE verwendet:
  • ECDH (Elliptic Curve Diffie-Hellman) auf secp256k1 für Schlüsselaustausch
  • HKDF-SHA256 für Schlüsselableitung
  • AES-256-GCM für symmetrische Verschlüsselung
  • TEE-Attestation, um zu verifizieren, dass das Modell in einer sicheren Enklave läuft
E2EE erfordert eine clientseitige Implementierung. Die Beispiele unten zeigen das vollständige Protokoll.

Wie E2EE funktioniert

1

Ephemeren Schlüsselpaar generieren

Der Client erzeugt ein secp256k1-Schlüsselpaar für diese Session.
2

TEE-Attestation abrufen

Der Client fragt /api/v1/tee/attestation an und erhält den Public Key des Modells, Attestation-Evidence und eine Nonce.
3

Attestation verifizieren

Der Client prüft Nonce-Übereinstimmung, deaktivierten Debug-Modus und Attestation-Gültigkeit.
4

Nachrichten verschlüsseln

Der Client verschlüsselt die Prompts mittels ECDH-Shared-Secret → HKDF → AES-GCM.
5

Request senden

Der Client sendet den Request mit E2EE-Headern (X-Venice-TEE-Client-Pub-Key, X-Venice-TEE-Model-Pub-Key, X-Venice-TEE-Signing-Algo).
6

TEE-Processing

Die TEE entschlüsselt den Request, verarbeitet ihn und verschlüsselt die Antwort.
7

Response entschlüsseln

Der Client erhält verschlüsselte Chunks und entschlüsselt sie mit dem Private Key.

Voraussetzungen

JavaScript (Node.js ESM):
npm install elliptic @noble/ciphers @noble/hashes
Python:
pip install cryptography ecdsa requests

Schritt 1: E2EE-Support des Modells prüfen

Zuerst über den /models-Endpoint prüfen, ob das Modell E2EE unterstützt.
async function getE2EEModels(apiKey) {
  const response = await fetch('https://api.venice.ai/api/v1/models', {
    headers: { Authorization: `Bearer ${apiKey}` },
  })
  const { data } = await response.json()

  return data.filter(model => model.model_spec?.capabilities?.supportsE2EE === true)
}

// Beispielnutzung
const models = await getE2EEModels('your-api-key')
console.log('E2EE Models:', models.map(m => m.id))
// Output: ['e2ee-qwen3-5-122b-a10b', 'e2ee-glm-5', ...]

Schritt 2: Ephemeres Schlüsselpaar generieren

Pro Session ein neues Schlüsselpaar generieren. Der Private Key sollte nur im Memory gehalten und nach Gebrauch sicher genullt werden.
import { ec as EC } from 'elliptic'

function generateEphemeralKeyPair() {
  const ec = new EC('secp256k1')
  const keyPair = ec.genKeyPair()

  return {
    privateKey: new Uint8Array(keyPair.getPrivate().toArray('be', 32)),
    publicKeyHex: keyPair.getPublic('hex'), // Unkomprimiertes Format (65 Bytes hex)
  }
}

// Sicherheit: Private Key nach Gebrauch nullen
function zeroFill(arr) {
  arr.fill(0)
}

Validierungs-Helpers

Verwende diese Helper-Funktionen, um Schlüssel und verschlüsselten Content vor dem Senden zu validieren.
function validateClientPubkey(pubkeyHex) {
  if (pubkeyHex.length !== 130 || !pubkeyHex.startsWith('04')) {
    throw new Error(`Client pubkey must be 130 hex chars starting with '04' (got ${pubkeyHex.length})`)
  }
}

function isValidEncrypted(s) {
  // Minimum: ephemeral_pub (65) + nonce (12) + tag (16) = 93 Bytes = 186 Hex-Zeichen
  return s.length >= 186 && /^[0-9a-fA-F]+$/.test(s)
}

Schritt 3: TEE-Attestation abrufen und verifizieren

Die Attestation beweist, dass das Modell in einer echten TEE läuft. Immer die Attestation verifizieren, bevor du dem Public Key des Modells vertraust.
Wichtig: Nonce-Länge — Die Client-Nonce muss 32 Bytes (64 Hex-Zeichen) lang sein. Manche TEE-Provider verlangen exakt 32 Bytes und lehnen kürzere Nonces ab.
import crypto from 'crypto'

async function fetchAndVerifyAttestation(modelId, apiKey) {
  // Client-Nonce für Replay-Schutz generieren (32 Bytes = 64 Hex-Zeichen)
  const clientNonce = crypto.randomBytes(32).toString('hex')

  const response = await fetch(
    `https://api.venice.ai/api/v1/tee/attestation?model=${encodeURIComponent(modelId)}&nonce=${clientNonce}`,
    { headers: { Authorization: `Bearer ${apiKey}` } }
  )

  const attestation = await response.json()

  // Attestation verifizieren
  if (attestation.verified !== true) {
    throw new Error('TEE attestation verification failed on server')
  }

  if (attestation.nonce !== clientNonce) {
    throw new Error('Attestation nonce mismatch - possible replay attack')
  }

  // Public Key des Modells für Verschlüsselung holen
  const modelPublicKey = attestation.signing_key || attestation.signing_public_key
  if (!modelPublicKey) {
    throw new Error('No signing key in attestation response')
  }

  return {
    modelPublicKey,
    signingAddress: attestation.signing_address,
    attestation,
  }
}

Schritt 4: Nachrichten verschlüsseln

User- und System-Nachrichten vor dem Senden verschlüsseln. Nur Nachrichten mit Rolle user und system müssen verschlüsselt werden.
Wenn E2EE-Header gesetzt sind, müssen alle Nachrichten mit Rolle user und system verschlüsselt sein. Sendet du in diesen Rollen Klartext, gibt es einen „Encrypted field is not valid hex”-Fehler.
import { gcm } from '@noble/ciphers/aes.js'
import { hkdf } from '@noble/hashes/hkdf.js'
import { sha256 } from '@noble/hashes/sha2.js'
import { ec as EC } from 'elliptic'
import crypto from 'crypto'

const HKDF_INFO = new TextEncoder().encode('ecdsa_encryption')

function encryptMessage(plaintext, modelPublicKeyHex) {
  const ec = new EC('secp256k1')

  // Public Key normalisieren (04-Präfix ggf. ergänzen)
  let normalizedKey = modelPublicKeyHex
  if (!normalizedKey.startsWith('04') && normalizedKey.length === 128) {
    normalizedKey = '04' + normalizedKey
  }

  const modelPublicKey = ec.keyFromPublic(normalizedKey, 'hex')

  // Ephemeres Schlüsselpaar für diese Nachricht generieren
  const ephemeralKeyPair = ec.genKeyPair()

  // ECDH-Shared-Secret
  const sharedSecret = ephemeralKeyPair.derive(modelPublicKey.getPublic())
  const sharedSecretBytes = new Uint8Array(sharedSecret.toArray('be', 32))

  // AES-Key per HKDF ableiten
  const aesKey = hkdf(sha256, sharedSecretBytes, undefined, HKDF_INFO, 32)

  // Zufällige Nonce
  const nonce = crypto.randomBytes(12)

  // Mit AES-GCM verschlüsseln
  const cipher = gcm(aesKey, nonce)
  const encrypted = cipher.encrypt(new TextEncoder().encode(plaintext))

  // Ephemeren Public Key holen (unkomprimiert)
  const ephemeralPublic = new Uint8Array(ephemeralKeyPair.getPublic(false, 'array'))

  // Kombinieren: ephemeral_public (65 Bytes) + nonce (12 Bytes) + ciphertext
  const result = new Uint8Array(65 + 12 + encrypted.length)
  result.set(ephemeralPublic, 0)
  result.set(nonce, 65)
  result.set(encrypted, 65 + 12)

  return Buffer.from(result).toString('hex')
}

function encryptMessagesForE2EE(messages, modelPublicKey) {
  return messages.map(msg => {
    if (msg.role === 'user' || msg.role === 'system') {
      return {
        ...msg,
        content: encryptMessage(msg.content, modelPublicKey),
      }
    }
    return msg
  })
}

Schritt 5: Request mit E2EE-Headern senden

Erforderliche Header setzen, um E2EE-Processing zu aktivieren.
HeaderBeschreibung
X-Venice-TEE-Client-Pub-KeyDein ephemerer Public Key (unkomprimiertes Hex, 130 Zeichen)
X-Venice-TEE-Model-Pub-KeyPublic Key des Modells aus der Attestation
X-Venice-TEE-Signing-AlgoImmer ecdsa
async function sendE2EERequest(messages, model, e2eeContext, apiKey) {
  // Nachrichten verschlüsseln
  const encryptedMessages = encryptMessagesForE2EE(messages, e2eeContext.modelPublicKey)

  const response = await fetch('https://api.venice.ai/api/v1/chat/completions', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      // E2EE-Header
      'X-Venice-TEE-Client-Pub-Key': e2eeContext.publicKeyHex,
      'X-Venice-TEE-Model-Pub-Key': e2eeContext.modelPublicKey,
      'X-Venice-TEE-Signing-Algo': 'ecdsa',
    },
    body: JSON.stringify({
      model,
      messages: encryptedMessages,
      stream: true, // E2EE benötigt Streaming
    }),
  })

  return response
}

Schritt 6: Response-Chunks entschlüsseln

Antworten von E2EE-Modellen sind hex-kodierte verschlüsselte Chunks. Entschlüssele jeden Chunk mit deinem Private Key.
import { gcm } from '@noble/ciphers/aes.js'
import { hkdf } from '@noble/hashes/hkdf.js'
import { sha256 } from '@noble/hashes/sha2.js'
import { ec as EC } from 'elliptic'

const HKDF_INFO = new TextEncoder().encode('ecdsa_encryption')

function hexToBytes(hex) {
  const h = hex.startsWith('0x') ? hex.slice(2) : hex
  const bytes = new Uint8Array(h.length / 2)
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = parseInt(h.substring(i * 2, i * 2 + 2), 16)
  }
  return bytes
}

function isHexEncrypted(s) {
  // Minimum: ephemeral_pub (65) + nonce (12) + tag (16) = 93 Bytes = 186 Hex-Zeichen
  if (s.length < 186) return false
  return /^[0-9a-fA-F]+$/.test(s)
}

function decryptChunk(ciphertextHex, clientPrivateKey) {
  const raw = hexToBytes(ciphertextHex)

  // Komponenten parsen
  const serverEphemeralPubKey = raw.slice(0, 65)
  const nonce = raw.slice(65, 65 + 12)
  const ciphertext = raw.slice(65 + 12)

  // ECDH mit dem ephemeren Schlüssel des Servers
  const ec = new EC('secp256k1')
  const clientKey = ec.keyFromPrivate(Buffer.from(clientPrivateKey))
  const serverKey = ec.keyFromPublic(Buffer.from(serverEphemeralPubKey))
  const sharedSecret = clientKey.derive(serverKey.getPublic())
  const sharedSecretBytes = new Uint8Array(sharedSecret.toArray('be', 32))

  // AES-Key ableiten
  const aesKey = hkdf(sha256, sharedSecretBytes, undefined, HKDF_INFO, 32)

  // Entschlüsseln
  const cipher = gcm(aesKey, nonce)
  const plaintext = cipher.decrypt(ciphertext)

  return new TextDecoder().decode(plaintext)
}

// Streaming-Response verarbeiten
async function processE2EEStream(response, clientPrivateKey) {
  const reader = response.body.getReader()
  const decoder = new TextDecoder()
  let fullContent = ''

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    const text = decoder.decode(value)
    const lines = text.split('\n')

    for (const line of lines) {
      if (!line.startsWith('data: ')) continue
      const data = line.slice(6)
      if (data === '[DONE]') continue

      try {
        const chunk = JSON.parse(data)
        const content = chunk.choices?.[0]?.delta?.content

        if (content && isHexEncrypted(content)) {
          const decrypted = decryptChunk(content, clientPrivateKey)
          fullContent += decrypted
          process.stdout.write(decrypted) // Echtzeit-Ausgabe
        } else if (content) {
          fullContent += content
          process.stdout.write(content)
        }
      } catch (e) {
        // Fehlerhafte Chunks überspringen
      }
    }
  }

  return fullContent
}

Vollständiges funktionierendes Beispiel

import elliptic from 'elliptic';
import { gcm } from '@noble/ciphers/aes.js';
import { hkdf } from '@noble/hashes/hkdf.js';
import { sha256 } from '@noble/hashes/sha2.js';
import crypto from 'crypto';

const EC = elliptic.ec;

const API_KEY = process.env.API_KEY_VENICE;
const BASE_URL = 'https://api.venice.ai/api/v1';
const MODEL = 'e2ee-qwen3-5-122b-a10b';
const HKDF_INFO = new TextEncoder().encode('ecdsa_encryption');

function hexToBytes(hex) {
  const bytes = new Uint8Array(hex.length / 2);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
  }
  return bytes;
}

async function main() {
  // Schritt 1: Ephemeres Schlüsselpaar generieren
  console.log('🔑 Generating ephemeral key pair...');
  const ec = new EC('secp256k1');
  const keyPair = ec.genKeyPair();
  const clientPublicKeyHex = keyPair.getPublic('hex');

  // Schritt 2: Attestation abrufen und verifizieren
  console.log('🔍 Fetching TEE attestation...');
  const clientNonce = crypto.randomBytes(32).toString('hex'); // 32 Bytes erforderlich
  const attestationRes = await fetch(
    `${BASE_URL}/tee/attestation?model=${MODEL}&nonce=${clientNonce}`,
    { headers: { Authorization: `Bearer ${API_KEY}` } }
  );
  const attestation = await attestationRes.json();

  if (attestation.verified !== true || attestation.nonce !== clientNonce) {
    throw new Error('Attestation verification failed');
  }

  const modelPublicKey = attestation.signing_key || attestation.signing_public_key;
  console.log('✅ TEE attestation verified');

  // Schritt 3: Nachricht verschlüsseln
  console.log('🔐 Encrypting message...');
  const plaintext = 'What is 2+2? Answer briefly.';

  // Public Key des Modells normalisieren und parsen
  let normalizedKey = modelPublicKey;
  if (!normalizedKey.startsWith('04') && normalizedKey.length === 128) {
    normalizedKey = '04' + normalizedKey;
  }

  const modelKey = ec.keyFromPublic(normalizedKey, 'hex');
  const ephemeralKeyPair = ec.genKeyPair();
  const sharedSecret = ephemeralKeyPair.derive(modelKey.getPublic());
  const sharedSecretBytes = new Uint8Array(sharedSecret.toArray('be', 32));
  const aesKey = hkdf(sha256, sharedSecretBytes, undefined, HKDF_INFO, 32);
  const nonce = crypto.randomBytes(12);
  const cipher = gcm(aesKey, nonce);
  const encrypted = cipher.encrypt(new TextEncoder().encode(plaintext));
  const ephemeralPublic = new Uint8Array(ephemeralKeyPair.getPublic(false, 'array'));

  const result = new Uint8Array(65 + 12 + encrypted.length);
  result.set(ephemeralPublic, 0);
  result.set(nonce, 65);
  result.set(encrypted, 77);

  const encryptedContent = Buffer.from(result).toString('hex');
  const messages = [{ role: 'user', content: encryptedContent }];

  // Schritt 4: E2EE-Request senden
  console.log('📤 Sending encrypted request...');
  const response = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
      'X-Venice-TEE-Client-Pub-Key': clientPublicKeyHex,
      'X-Venice-TEE-Model-Pub-Key': modelPublicKey,
      'X-Venice-TEE-Signing-Algo': 'ecdsa',
    },
    body: JSON.stringify({ model: MODEL, messages, stream: true }),
  });

  // Schritt 5: Antwort entschlüsseln
  console.log('📥 Decrypting response...\n');
  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const text = decoder.decode(value);
    for (const line of text.split('\n')) {
      if (!line.startsWith('data: ') || line.includes('[DONE]')) continue;

      try {
        const chunk = JSON.parse(line.slice(6));
        const content = chunk.choices?.[0]?.delta?.content;
        if (!content) continue;

        if (/^[0-9a-fA-F]+$/.test(content) && content.length >= 186) {
          // Entschlüsseln
          const raw = hexToBytes(content);
          const serverEphemeralPub = raw.slice(0, 65);
          const nonce = raw.slice(65, 77);
          const ciphertext = raw.slice(77);

          const serverKey = ec.keyFromPublic(Buffer.from(serverEphemeralPub));
          const sharedSecret = keyPair.derive(serverKey.getPublic());
          const aesKey = hkdf(sha256, new Uint8Array(sharedSecret.toArray('be', 32)), undefined, HKDF_INFO, 32);
          const cipher = gcm(aesKey, nonce);
          const plaintext = new TextDecoder().decode(cipher.decrypt(ciphertext));
          process.stdout.write(plaintext);
        } else {
          process.stdout.write(content);
        }
      } catch {}
    }
  }

  console.log('\n\n🔐 Response decrypted end-to-end');
}

main().catch(console.error);

E2EE-Einschränkungen

E2EE hat einige Einschränkungen aufgrund der Verschlüsselungsanforderungen:
FeatureStatus
StreamingPflicht (Non-Streaming nicht unterstützt)
Web SearchDeaktiviert (würde Inhalte leaken)
Datei-UploadsNicht unterstützt
Function CallingNicht unterstützt
Venice-System-PromptDeaktiviert (muss clientseitig verschlüsselt werden)

Sicherheits-Best-Practices

  1. Pro Session neues Schlüsselpaar — keine ephemeren Keys wiederverwenden
  2. Private Keys nullen — Private-Key-Bytes nach Gebrauch aus dem Memory löschen
  3. Attestation verifizieren — immer verified: true und Nonce-Match prüfen
  4. Debug-Modus prüfen — Attestations von Debug-Enklaven ablehnen
  5. Streaming nutzen — E2EE benötigt Streaming für korrektes Chunking
  6. Fehler sauber behandeln — Decryption-Fehler nicht an Nutzer durchreichen
  7. 32-Byte-Nonces nutzen — TEE-Provider verlangen genau 32 Bytes

Best Practices

Verlasse dich nicht nur auf das verified: true. Parse den Intel-TDX-Quote clientseitig und prüfe, dass die Messungen den erwarteten Werten entsprechen. Für NVIDIA-GPUs die Attestation über NVIDIAs Verifikationsdienst prüfen.
Für jede Attestation-Anfrage eine neue zufällige Nonce erzeugen. Das verhindert Replay-Angriffe, bei denen ein Angreifer eine veraltete Attestation ausliefern könnte.
Der Signing-Key sollte an das TDX-REPORTDATA-Feld gebunden sein. Das beweist, dass der Schlüssel innerhalb der Enklave erzeugt wurde.
Sicherstellen, dass die TDX-Attestation keine Debug-Flags gesetzt hat. Eine Debug-Enklave kann inspiziert werden und sollte in der Produktion nicht vertraut werden.
E2EE erfordert sorgfältige kryptografische Implementierung. Nutze unsere offiziellen SDKs, statt das Protokoll selbst zu implementieren.

Modell-Fähigkeiten prüfen

Du kannst über den Models-Endpoint prüfen, ob ein Modell TEE oder E2EE unterstützt:
curl https://api.venice.ai/api/v1/models \
  -H "Authorization: Bearer $API_KEY_VENICE" | jq '.data[] | select(.model_spec.capabilities.supportsTeeAttestation == true or .model_spec.capabilities.supportsE2EE == true) | {id, tee: .model_spec.capabilities.supportsTeeAttestation, e2ee: .model_spec.capabilities.supportsE2EE}'

Fehlerbehandlung

FehlerUrsacheLösung
TEE attestation verification failedAttestation hat die Validierung nicht bestandenErneut versuchen oder Support kontaktieren
Attestation nonce mismatchMöglicher Replay-AngriffFrische Nonce generieren
TDX debug mode detectedEnklave ist im Debug-ModusNicht für Produktion verwenden
Failed to decrypt fieldE2EE-Decryption serverseitig fehlgeschlagenEigene Verschlüsselungs-Implementierung prüfen
E2EE requires streamingNon-Streaming-Request an E2EE-Modellstream: true setzen
Encrypted field is not valid hexKlartext mit E2EE-Headern gesendetAlle User-/System-Nachrichten verschlüsseln
Invalid public keyFalsches Key-Format130 Hex-Zeichen beginnend mit 04 verwenden

Fehlerbehebung

Die Nonce-Länge ist falsch. TEE-Provider verlangen exakt 32 Bytes (64 Hex-Zeichen).
  • crypto.randomBytes(32).toString('hex') (JS) oder secrets.token_hex(32) (Python) verwenden
  • Häufiger Fehler: secrets.token_hex(16) erzeugt 32 Hex-Zeichen (16 Bytes), nicht 32 Bytes
  • Prüfen, ob das Modell E2EE unterstützt (supportsE2EE: true)
  • API-Schlüssel-Gültigkeit und Zugriff auf das angeforderte Modell verifizieren
  • Netzwerkverbindung zur Venice-API prüfen
  • Sicherstellen, dass derselbe Private Key verwendet wird, der den in den Headern gesendeten Public Key erzeugt hat
  • Prüfen, dass der Response-Content tatsächlich hex-kodiert ist (E2EE aktiv)
  • Verifizieren, dass der Model-Public-Key dem für die Verschlüsselung verwendeten entspricht
  • Alle user- und system-Nachrichten müssen verschlüsselt sein, wenn E2EE-Header vorhanden sind
  • Sicherstellen, dass der verschlüsselte Content die isValidEncrypted()-Validierung passiert (mindestens 186 Hex-Zeichen)
  • Prüfen, dass die Verschlüsselungs-Ausgabe lowercase-Hex ohne Präfixe ist
  • Client-Public-Key muss exakt 130 Hex-Zeichen sein und mit 04 beginnen
  • Das Helper-validateClientPubkey() vor dem Senden zur Formatprüfung verwenden
  • Sicherstellen, dass unkomprimiertes Public-Key-Format verwendet wird (65 Bytes = 130 Hex-Zeichen)
  • Modell-ID prüfen und sicherstellen, dass das Modell E2EE unterstützt
  • /models-Endpoint nutzen, um verfügbare E2EE-Modelle zu verifizieren

Ressourcen